/***************************************************************************** This is a C++ source code file. This file contains example Advanced Custom Study functions. It also contains functions for some built-in studies in Sierra Chart. *****************************************************************************/ #include "sierrachart.h" enum TimeAndSalesStudyFlagsEnum { TIME_AND_SALES_STUDY_UNKNOWN = 0, TIME_AND_SALES_STUDY_PRICE = 1, TIME_AND_SALES_STUDY_VOLUME = 2, TIME_AND_SALES_STUDY_TIME = 3, TIME_AND_SALES_STUDY_BID_AND_ASK = 4, TIME_AND_SALES_STUDY_BID_SIZE = 5, TIME_AND_SALES_STUDY_ASK_SIZE = 6, TIME_AND_SALES_STUDY_MILLISECONDS = 7, TIME_AND_SALES_STUDY_TOTAL_BID_SIZE_DEPTH = 8, TIME_AND_SALES_STUDY_TOTAL_ASK_SIZE_DEPTH = 9 }; /****************************************************************************/ SCDLLName("Sierra Chart Custom Studies and Examples") /*============================================================================ This example code calculates a simple moving average (30 period by default). ----------------------------------------------------------------------------*/ SCSFExport scsf_SimpMovAvg(SCStudyInterfaceRef sc) { SCSubgraphRef Subgraph_Average = sc.Subgraph[0]; SCInputRef Input_Length = sc.Input[0]; // Set configuration variables if (sc.SetDefaults) { // Set the configuration and defaults sc.GraphName = "Simple Moving Average"; sc.StudyDescription = "Example function for calculating a simple moving average."; // 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 Subgraph_Average.Name = "Average"; // Set the color, style and line width for the subgraph Subgraph_Average.PrimaryColor = RGB(0,255,0); Subgraph_Average.DrawStyle = DRAWSTYLE_LINE; Subgraph_Average.LineWidth = 2; // Set the Length input and default it to 30 Input_Length.Name = "Length"; Input_Length.SetInt(30); Input_Length.SetIntLimits(1,MAX_STUDY_LENGTH); Input_Length.SetDescription("The number of bars to average."); sc.AutoLoop = 1; sc.AlertOnlyOncePerBar = true; // Must return before doing any data processing if sc.SetDefaults is set return; } // Do data processing // Set the index of the first array element to begin drawing at sc.DataStartIndex = Input_Length.GetInt() - 1; // Calculate a simple moving average from the base data sc.SimpleMovAvg(sc.Close,Subgraph_Average,Input_Length.GetInt()); if (sc.CrossOver(Subgraph_Average, sc.Close)) { // Since we are using auto-looping we do not specify the Index parameter. sc.SetAlert(1, "Moving average has crossed last price."); } } /*==========================================================================*/ SCSFExport scsf_SimpMovAvgWithDynamicLength(SCStudyInterfaceRef sc) { SCSubgraphRef Subgraph_Average = sc.Subgraph[0]; SCInputRef Input_Length = sc.Input[0]; // Set configuration variables if (sc.SetDefaults) { // Set the configuration and defaults sc.GraphName = "Simple Moving Average With Dynamic Length"; sc.StudyDescription = "Example function for calculating a simple moving average with a length based on the time frame of the bars."; // 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 Subgraph_Average.Name = "Average"; // Set the color and style of the graph line. If these are not set, the default will be used. Subgraph_Average.PrimaryColor = RGB(0,255,0); Subgraph_Average.DrawStyle = DRAWSTYLE_LINE; Subgraph_Average.LineWidth = 3; // Make the Length input and default it to 30 Input_Length.Name = "Length"; Input_Length.SetInt(30); Input_Length.SetIntLimits(1,MAX_STUDY_LENGTH); sc.AutoLoop = 1; // Must return before doing any data processing if sc.SetDefaults is set return; } Input_Length.SetInt(30 / (sc.SecondsPerBar/60) * 50); // Set the index of the first array element to begin drawing at sc.DataStartIndex = Input_Length.GetInt(); - 1; // Calculate a simple moving average from the base data sc.SimpleMovAvg(sc.Close,Subgraph_Average,Input_Length.GetInt()); } /*============================================================================ Parabolic study function. ----------------------------------------------------------------------------*/ SCSFExport scsf_Parabolic(SCStudyInterfaceRef sc) { SCSubgraphRef Subgraph_Parabolic = sc.Subgraph[0]; SCInputRef Input_InputDataHigh = sc.Input[0]; SCInputRef Input_InputDataLow = sc.Input[1]; SCInputRef Input_StartAccelerationFactor = sc.Input[3]; SCInputRef Input_AccelerationIncrement = sc.Input[4]; SCInputRef Input_MaxAccelerationFactor = sc.Input[5]; SCInputRef Input_AdjustForGap = sc.Input[6]; SCInputRef Input_Version = sc.Input[7]; // Set configuration variables if (sc.SetDefaults) { // Set the configuration and defaults sc.GraphName = "Parabolic"; sc.StudyDescription = ""; sc.DrawZeros = false; sc.GraphRegion = 0; sc.ValueFormat = 3; // 3 decimal places sc.AutoLoop = 1; Subgraph_Parabolic.Name = "Parabolic"; Subgraph_Parabolic.DrawStyle = DRAWSTYLE_DASH; Subgraph_Parabolic.PrimaryColor = RGB(0,255,0); Input_InputDataHigh.Name = "Input Data High"; Input_InputDataHigh.SetInputDataIndex(SC_HIGH); Input_InputDataLow.Name = "Input Data Low"; Input_InputDataLow.SetInputDataIndex(SC_LOW); Input_Version.SetInt(1); Input_StartAccelerationFactor.Name = "Start Acceleration Factor"; Input_StartAccelerationFactor.SetFloat(0.02f); Input_StartAccelerationFactor.SetFloatLimits(0.000001f,(float)MAX_STUDY_LENGTH); Input_AccelerationIncrement.Name = "Acceleration Increment"; Input_AccelerationIncrement.SetFloat(0.02f); Input_AccelerationIncrement.SetFloatLimits(0.00001f, 100.0f); Input_MaxAccelerationFactor.Name = "Max Acceleration Factor"; Input_MaxAccelerationFactor.SetFloat(0.2f); Input_MaxAccelerationFactor.SetFloatLimits(0.000001f,(float)MAX_STUDY_LENGTH); Input_AdjustForGap.Name = "Adjust for Gap"; Input_AdjustForGap.SetYesNo(0); // No return; } if (Input_Version.GetInt() == 0) { Input_InputDataHigh.SetInputDataIndex(SC_HIGH); Input_InputDataLow.SetInputDataIndex(SC_LOW); } // Do data processing sc.DataStartIndex = 1; sc.Parabolic( sc.BaseDataIn, sc.BaseDateTimeIn, Subgraph_Parabolic, sc.Index, Input_StartAccelerationFactor.GetFloat(), Input_AccelerationIncrement.GetFloat(), Input_MaxAccelerationFactor.GetFloat(), Input_AdjustForGap.GetYesNo(), Input_InputDataHigh.GetInputDataIndex(), Input_InputDataLow.GetInputDataIndex() ); } /*============================================================================ SuperTrend Stop study function. ----------------------------------------------------------------------------*/ SCSFExport scsf_SuperTrendStop(SCStudyInterfaceRef sc) { SCSubgraphRef Subgraph_Stop = sc.Subgraph[0]; SCSubgraphRef Subgraph_Median = sc.Subgraph[1]; SCFloatArrayRef Array_TrueRange = Subgraph_Stop.Arrays[0]; SCFloatArrayRef Array_AvgTrueRange = Subgraph_Stop.Arrays[1]; SCFloatArrayRef Array_Trend = Subgraph_Stop.Arrays[2]; SCInputRef Input_ATRMultiplier = sc.Input[0]; SCInputRef Input_ATRPeriod = sc.Input[1]; SCInputRef Input_MedianPeriod = sc.Input[2]; // Set configuration variables if (sc.SetDefaults) { // Set the configuration and defaults sc.GraphName = "SuperTrend Stop"; sc.StudyDescription = ""; sc.DrawZeros = false; sc.GraphRegion = 0; sc.ValueFormat = sc.BaseGraphValueFormat; sc.AutoLoop = 1; Subgraph_Stop.Name = "Stop"; Subgraph_Stop.DrawStyle = DRAWSTYLE_DASH; Subgraph_Stop.LineWidth = 2; Subgraph_Stop.PrimaryColor = COLOR_BLUE; Subgraph_Stop.SecondaryColor = COLOR_RED; Subgraph_Stop.SecondaryColorUsed = 1; Input_ATRMultiplier.Name = "ATR Multiplier"; Input_ATRMultiplier.SetFloat(2); Input_ATRMultiplier.SetFloatLimits(0.000001f,(float)MAX_STUDY_LENGTH); Input_ATRPeriod.Name = "ATR Period"; Input_ATRPeriod.SetInt(3); Input_ATRPeriod.SetIntLimits(1,MAX_STUDY_LENGTH); Input_MedianPeriod.Name = "Median Period"; Input_MedianPeriod.SetInt(3); Input_MedianPeriod.SetIntLimits(1,MAX_STUDY_LENGTH); return; } // Do data processing sc.MovingMedian(sc.HLAvg, Subgraph_Median, sc.Index, Input_MedianPeriod.GetInt()); sc.ATR(sc.BaseDataIn, Array_TrueRange, Array_AvgTrueRange, sc.Index, Input_ATRPeriod.GetInt(), MOVAVGTYPE_SIMPLE); if (sc.Index == 0) { sc.ValueFormat = sc.BaseGraphValueFormat; Subgraph_Stop[sc.Index] = sc.Close[sc.Index]; Array_Trend[sc.Index] = 1; return; } if (sc.FormattedEvaluate(sc.Close[sc.Index], sc.ValueFormat, GREATER_OPERATOR, Subgraph_Stop[sc.Index-1], sc.ValueFormat)) { Array_Trend[sc.Index] = 1; float NewStop = Subgraph_Median[sc.Index] - Input_ATRMultiplier.GetFloat()*Array_AvgTrueRange[sc.Index-1]; if (Array_Trend[sc.Index-1] < 0) { Subgraph_Stop[sc.Index] = NewStop; } else { Subgraph_Stop[sc.Index] = max(NewStop, Subgraph_Stop[sc.Index-1]); } } else if (sc.FormattedEvaluate(sc.Close[sc.Index], sc.ValueFormat, LESS_OPERATOR, Subgraph_Stop[sc.Index-1], sc.ValueFormat)) { Array_Trend[sc.Index] = -1; float NewStop = Subgraph_Median[sc.Index] + Input_ATRMultiplier.GetFloat()*Array_AvgTrueRange[sc.Index-1]; if (Array_Trend[sc.Index-1] > 0) { Subgraph_Stop[sc.Index] = NewStop; } else { Subgraph_Stop[sc.Index] = min(NewStop, Subgraph_Stop[sc.Index-1]); } } else { Array_Trend[sc.Index] = Array_Trend[sc.Index-1]; Subgraph_Stop[sc.Index] = Subgraph_Stop[sc.Index-1]; } Subgraph_Stop.DataColor[sc.Index] = Array_Trend[sc.Index] > 0 ? Subgraph_Stop.PrimaryColor : Subgraph_Stop.SecondaryColor; } /*============================================================================ This function is an example of how to calculate high - low * 2.5. ----------------------------------------------------------------------------*/ SCSFExport scsf_SimpleArithmeticExample(SCStudyInterfaceRef sc) { SCSubgraphRef Subgraph_Line = sc.Subgraph[0]; // Set configuration variables if (sc.SetDefaults) { // Set the configuration and defaults sc.GraphName = "SimpleArithmeticExample"; sc.StudyDescription = "This function is an example of how to calculate (high-low)*10."; Subgraph_Line.Name = "Line"; Subgraph_Line.DrawStyle = DRAWSTYLE_LINE; Subgraph_Line.PrimaryColor = RGB(0,255,0); // Green sc.AutoLoop = 1; return; } // Do data processing Subgraph_Line[sc.Index] = (sc.High[sc.Index] - sc.Low[sc.Index]) * 10; } /*==========================================================================*/ SCSFExport scsf_InsideBar(SCStudyInterfaceRef sc) { SCSubgraphRef Subgraph_IB = sc.Subgraph[0]; // Set configuration variables if (sc.SetDefaults) { // Set the configuration and defaults sc.GraphName = "Inside Bar"; sc.GraphRegion = 0; Subgraph_IB.Name = "IB"; Subgraph_IB.DrawStyle = DRAWSTYLE_COLOR_BAR; Subgraph_IB.PrimaryColor = RGB(255,128,0); Subgraph_IB.DrawZeros = false; sc.AutoLoop = 1; return; } // Array references SCFloatArrayRef High = sc.High; SCFloatArrayRef Low = sc.Low; // Do data processing if (High[sc.Index] < High[sc.Index - 1] && Low[sc.Index] > Low[sc.Index - 1]) Subgraph_IB[sc.Index] = High[sc.Index]; else Subgraph_IB[sc.Index] = 0; } /*==========================================================================*/ SCSFExport scsf_InsideBarMarkttechnik(SCStudyInterfaceRef sc) { SCSubgraphRef Subgraph_IB = sc.Subgraph[0]; // Set configuration variables if (sc.SetDefaults) { // Set the configuration and defaults sc.GraphName = "Inside Bar - Markttechnik"; sc.GraphRegion = 0; sc.ValueFormat= VALUEFORMAT_INHERITED; Subgraph_IB.Name = "IB"; Subgraph_IB.DrawStyle = DRAWSTYLE_COLOR_BAR; Subgraph_IB.PrimaryColor = RGB(255,128,0); Subgraph_IB.DrawZeros = false; sc.AutoLoop = 1; return; } // Array references SCFloatArrayRef High = sc.High; SCFloatArrayRef Low = sc.Low; // Do data processing if (High[sc.Index] < High[sc.Index - 1] && Low[sc.Index] > Low[sc.Index - 1]) Subgraph_IB[sc.Index] = High[sc.Index]; else Subgraph_IB[sc.Index] = 0; } /*==========================================================================*/ SCSFExport scsf_OutsideBar(SCStudyInterfaceRef sc) { SCSubgraphRef Subgraph_OutsideBar = sc.Subgraph[0]; SCInputRef Input_IncludeEqualHighLow = sc.Input[0]; if (sc.SetDefaults) { // Set the configuration and defaults sc.GraphName = "Outside Bar"; sc.GraphRegion = 0; Subgraph_OutsideBar.Name = "OB"; Subgraph_OutsideBar.DrawStyle = DRAWSTYLE_COLOR_BAR; Subgraph_OutsideBar.LineWidth = 1; Subgraph_OutsideBar.PrimaryColor = RGB(255,128,0); Subgraph_OutsideBar.DrawZeros = false; Input_IncludeEqualHighLow.Name = "Include Equal High Low"; Input_IncludeEqualHighLow.SetYesNo(false); sc.AutoLoop = 1; return; } // Array references SCFloatArrayRef High = sc.High; SCFloatArrayRef Low = sc.Low; // Do data processing if (Input_IncludeEqualHighLow.GetYesNo() == 0 && High[sc.Index] > High[sc.Index - 1] && Low[sc.Index] < Low[sc.Index - 1]) { Subgraph_OutsideBar[sc.Index] = High[sc.Index]; } else if (Input_IncludeEqualHighLow.GetYesNo() != 0 && ( (High[sc.Index] >= High[sc.Index - 1] && Low[sc.Index] < Low[sc.Index - 1]) || (High[sc.Index] > High[sc.Index - 1] && Low[sc.Index] <= Low[sc.Index - 1]) ) ) { Subgraph_OutsideBar[sc.Index] = High[sc.Index]; } else { Subgraph_OutsideBar[sc.Index] = 0; } } /*============================================================================ This function is an example of how to use the GetChartArray function. ----------------------------------------------------------------------------*/ SCSFExport scsf_GetChartArrayExample(SCStudyInterfaceRef sc) { SCSubgraphRef Subgraph_Prices = sc.Subgraph[0]; SCSubgraphRef Subgraph_DateTime = sc.Subgraph[1]; // Set configuration variables if (sc.SetDefaults) { // Set the configuration and defaults sc.GraphName = "GetChartArrayExample"; sc.StudyDescription = "This function is an example of how to use the GetChartArray function."; Subgraph_Prices.Name = "Prices"; Subgraph_Prices.DrawStyle = DRAWSTYLE_LINE; Subgraph_Prices.PrimaryColor = RGB(0,255,0); Subgraph_DateTime.Name = "Date Time"; Subgraph_DateTime.DrawStyle = DRAWSTYLE_LINE; Subgraph_DateTime.PrimaryColor = RGB(255,0,255); sc. AutoLoop = 1; return; } // Do data processing SCDateTimeArray DateTimeArray; SCFloatArray PriceArray; // Get the date-time array from chart 1 sc.GetChartDateTimeArray(1, DateTimeArray); if (DateTimeArray.GetArraySize() == 0) return; // The DateTimeArray may not exist or is empty -- either way we can't do anything with it // Get the close/last array from chart 1 sc.GetChartArray(1, SC_LAST, PriceArray); if (PriceArray.GetArraySize() == 0) return; // The PriceArray may not exist or is empty -- either way we can't do anything with it // Copy the price array value from chart 1 to subgraph 1. Most likely // the array from chart 1 is not the same size as the array this study // function is applied to. Therefore there is not going to be a correct // column to column correspondence. However, this is just a simple example. Subgraph_Prices[sc.Index] = PriceArray[sc.Index]; //copy the date time array from chart 1 to subgraph 2 Subgraph_DateTime[sc.Index] = (float)DateTimeArray[sc.Index]; } /*============================================================================ This function is an example of how to use the GetStudyArray function. ----------------------------------------------------------------------------*/ SCSFExport scsf_GetStudyArrayExample(SCStudyInterfaceRef sc) { SCSubgraphRef Subgraph_Line = sc.Subgraph[0]; // Set configuration variables if (sc.SetDefaults) { // Set the configuration and defaults sc.GraphName = "GetStudyArrayExample"; sc.StudyDescription = "This function is an example of how to use the GetStudyArray function."; Subgraph_Line.Name = "Line"; Subgraph_Line.DrawStyle = DRAWSTYLE_LINE; Subgraph_Line.PrimaryColor = RGB(0,255,0); sc.AutoLoop = 1; return; } // Do data processing SCFloatArray StudyArray; // Get first Subgraph from study #1. sc.GetStudyArray(1, 1, StudyArray); if (StudyArray.GetArraySize() == 0) return; // The StudyArray may not exist or is empty. Either way we cannot do anything with it Subgraph_Line[sc.Index] = StudyArray[sc.Index]; } /*============================================================================ Calculates the adaptive moving average. ----------------------------------------------------------------------------*/ SCSFExport scsf_AdaptiveMovingAverage(SCStudyInterfaceRef sc) { SCSubgraphRef Subgraph_Avg = sc.Subgraph[0]; SCInputRef Input_InputData = sc.Input[0]; SCInputRef Input_Length = sc.Input[3]; SCInputRef Input_FastSmoothingConstant = sc.Input[4]; SCInputRef Input_SlowSmoothingConstant = sc.Input[5]; if (sc.SetDefaults) { // Set the configuration and defaults sc.GraphName = "Moving Average - Adaptive"; sc.StudyDescription = "Calculates the adaptive moving average."; sc.GraphRegion = 0; sc.ValueFormat = VALUEFORMAT_INHERITED; Subgraph_Avg.Name = "Avg"; Subgraph_Avg.DrawStyle = DRAWSTYLE_LINE; Subgraph_Avg.PrimaryColor = RGB(0,255,0); 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_FastSmoothingConstant.Name = "Fast Smoothing Constant"; Input_FastSmoothingConstant.SetFloat(2.0f); Input_FastSmoothingConstant.SetFloatLimits(0.0001f, (float)MAX_STUDY_LENGTH); Input_SlowSmoothingConstant.Name = "Slow Smoothing Constant"; Input_SlowSmoothingConstant.SetFloat(30.0f); Input_SlowSmoothingConstant.SetFloatLimits(0.0001f, (float)MAX_STUDY_LENGTH); sc.AutoLoop = 1; return; } // Do data processing sc.AdaptiveMovAvg(sc.BaseDataIn[Input_InputData.GetInputDataIndex()], Subgraph_Avg, Input_Length.GetInt(), Input_FastSmoothingConstant.GetFloat(), Input_SlowSmoothingConstant.GetFloat()); } /*============================================================================ Calculates the Moving Average - Adaptive Binary Wave ----------------------------------------------------------------------------*/ SCSFExport scsf_MovingAverageAdaptiveBinaryWave(SCStudyInterfaceRef sc) { SCSubgraphRef Subgraph_Wave = sc.Subgraph[0]; SCFloatArrayRef Array_AdaptiveMovingAverage = Subgraph_Wave.Arrays[0]; SCFloatArrayRef Array_StdDev = Subgraph_Wave.Arrays[1]; SCInputRef Input_InputData = sc.Input[0]; SCInputRef Input_Length = sc.Input[1]; SCInputRef Input_FastSmoothingConstant = sc.Input[2]; SCInputRef Input_SlowSmoothingConstant = sc.Input[3]; SCInputRef Input_FilterPercent = sc.Input[4]; if (sc.SetDefaults) { // Set the configuration and defaults sc.GraphName = "Moving Average - Adaptive Binary Wave"; sc.ValueFormat = 0; sc.ScaleIncrement = 1.0f; sc.AutoLoop = 1; // subgraphs Subgraph_Wave.Name = "Binary Wave"; Subgraph_Wave.DrawStyle = DRAWSTYLE_LINE; Subgraph_Wave.PrimaryColor = RGB(0,0,255); Subgraph_Wave.DrawZeros = 1; // inputs 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_FastSmoothingConstant.Name = "Fast Smoothing Constant"; Input_FastSmoothingConstant.SetFloat(2.0f); Input_FastSmoothingConstant.SetFloatLimits(0.0001f, (float)MAX_STUDY_LENGTH); Input_SlowSmoothingConstant.Name = "Slow Smoothing Constant"; Input_SlowSmoothingConstant.SetFloat(30.0f); Input_SlowSmoothingConstant.SetFloatLimits(0.0001f, (float)MAX_STUDY_LENGTH); Input_FilterPercent.Name = "Filter Percent"; Input_FilterPercent.SetFloat(25.0f); Input_FilterPercent.SetFloatLimits(0.0f, 100.0f); return; } // Do data processing sc.AdaptiveMovAvg(sc.BaseDataIn[Input_InputData.GetInputDataIndex()], Array_AdaptiveMovingAverage, Input_Length.GetInt(), Input_FastSmoothingConstant.GetFloat(), Input_SlowSmoothingConstant.GetFloat()); sc.StdDeviation(Array_AdaptiveMovingAverage, Array_StdDev, Input_Length.GetInt()); float Filter = Input_FilterPercent.GetFloat() / 100.0f * Array_StdDev[sc.Index]; float& AMALow = sc.GetPersistentFloat(0); float& AMAHigh = sc.GetPersistentFloat(1); if (sc.Index == 0) { AMALow = Array_AdaptiveMovingAverage[0]; AMAHigh = Array_AdaptiveMovingAverage[0]; } else { if (Array_AdaptiveMovingAverage[sc.Index] < Array_AdaptiveMovingAverage[sc.Index-1]) AMALow = Array_AdaptiveMovingAverage[sc.Index]; if (Array_AdaptiveMovingAverage[sc.Index] > Array_AdaptiveMovingAverage[sc.Index-1]) AMAHigh = Array_AdaptiveMovingAverage[sc.Index]; } if (Array_AdaptiveMovingAverage[sc.Index] - AMALow > Filter) Subgraph_Wave[sc.Index] = 1.0; else if (AMAHigh - Array_AdaptiveMovingAverage[sc.Index] > Filter) Subgraph_Wave[sc.Index] = -1.0; else Subgraph_Wave[sc.Index] = 0; } /*============================================================================ This function is only used internally by the other Time and Sales functions. This needs to be above the other Time and Sales functions that use this function. This function fills in a study Subgraph array with the Time and Sales Price, Volume, or Time based on what Flag has been set. ----------------------------------------------------------------------------*/ void TimeAndSales(SCStudyInterfaceRef sc, TimeAndSalesStudyFlagsEnum Flag) { SCSubgraphRef FirstSubgraph = sc.Subgraph[0]; SCSubgraphRef SecondSubgraph = sc.Subgraph[1]; SCSubgraphRef ThirdSubgraph = sc.Subgraph[2]; SCInputRef InVolumeMinFilter = sc.Input[2]; SCInputRef InVolumeMaxFilter = sc.Input[3]; int& EarliestIndex = sc.GetPersistentInt(1); // This is the earliest index we updated on the last call // Get the Time and Sales c_SCTimeAndSalesArray TimeSales; sc.GetTimeAndSales(TimeSales); int TimeSalesSize = TimeSales.Size(); if (TimeSalesSize == 0) return; // No Time and Sales data available for the symbol // Loop through the Time and Sales int OutputArrayIndex = sc.ArraySize; for (int TSIndex = TimeSalesSize - 1; TSIndex >= 0; --TSIndex) { s_TimeAndSales TimeAndSalesRecord = TimeSales[TSIndex]; TimeAndSalesRecord *= sc.RealTimePriceMultiplier; float Volume = TimeAndSalesRecord.Volume * sc.MultiplierFromVolumeValueFormat(); if (Flag == TIME_AND_SALES_STUDY_PRICE || Flag == TIME_AND_SALES_STUDY_VOLUME || Flag == TIME_AND_SALES_STUDY_TIME ) { if (Volume < (unsigned int)InVolumeMinFilter.GetInt() || (Volume > (unsigned int)InVolumeMaxFilter.GetInt() && InVolumeMaxFilter.GetInt() > 0) || TimeAndSalesRecord.Type == SC_TS_BIDASKVALUES ) continue; } else if (Flag == TIME_AND_SALES_STUDY_BID_AND_ASK || Flag == TIME_AND_SALES_STUDY_BID_SIZE || Flag == TIME_AND_SALES_STUDY_ASK_SIZE || Flag == TIME_AND_SALES_STUDY_TOTAL_BID_SIZE_DEPTH || Flag == TIME_AND_SALES_STUDY_TOTAL_ASK_SIZE_DEPTH) { if (TimeAndSalesRecord.Type != SC_TS_BIDASKVALUES) continue; } if (Flag == TIME_AND_SALES_STUDY_PRICE) // Price { --OutputArrayIndex; if (OutputArrayIndex < 0) break; if (TimeAndSalesRecord.Type == SC_TS_BID) { FirstSubgraph[OutputArrayIndex] = TimeAndSalesRecord.Price; SecondSubgraph[OutputArrayIndex] = 0.0f; ThirdSubgraph[OutputArrayIndex] = 0.0f; } else if (TimeAndSalesRecord.Type == SC_TS_ASK) { FirstSubgraph[OutputArrayIndex] = 0.0f; SecondSubgraph[OutputArrayIndex] = TimeAndSalesRecord.Price; ThirdSubgraph[OutputArrayIndex] = 0.0f; } else { FirstSubgraph[OutputArrayIndex] = 0.0f; SecondSubgraph[OutputArrayIndex] = 0.0f; ThirdSubgraph[OutputArrayIndex] = TimeAndSalesRecord.Price; } } else if (Flag == TIME_AND_SALES_STUDY_VOLUME) // Volume { --OutputArrayIndex; if (OutputArrayIndex < 0) break; if (TimeAndSalesRecord.Type == SC_TS_BID) { FirstSubgraph[OutputArrayIndex] = (float)Volume; SecondSubgraph[OutputArrayIndex] = 0.0f; ThirdSubgraph[OutputArrayIndex] = 0.0f; } else if (TimeAndSalesRecord.Type == SC_TS_ASK) { FirstSubgraph[OutputArrayIndex] = 0.0f; SecondSubgraph[OutputArrayIndex] = (float)Volume; ThirdSubgraph[OutputArrayIndex] = 0.0f; } else { FirstSubgraph[OutputArrayIndex] = 0.0f; SecondSubgraph[OutputArrayIndex] = 0.0f; ThirdSubgraph[OutputArrayIndex] = (float)Volume; } } else if (Flag == TIME_AND_SALES_STUDY_TIME) // Time { --OutputArrayIndex; if (OutputArrayIndex < 0) break; // Adjust a time and sales record date-time // TimeSales is a s_TimeAndSales record requested with sc.GetTimeAndSales(). SCDateTime TempDateTime = TimeAndSalesRecord.DateTime; TempDateTime += sc.TimeScaleAdjustment; // Apply the time zone offset for the chart TempDateTime.ClearDate(); // Remove the date part so only the time remains FirstSubgraph[OutputArrayIndex] = (float)TempDateTime; // Put in the output array } else if (Flag == TIME_AND_SALES_STUDY_BID_AND_ASK) // Bid & Ask { --OutputArrayIndex; if (OutputArrayIndex < 0) break; FirstSubgraph[OutputArrayIndex] = TimeAndSalesRecord.Bid; SecondSubgraph[OutputArrayIndex] = TimeAndSalesRecord.Ask; } else if (Flag == TIME_AND_SALES_STUDY_BID_SIZE) // Bid size { float BidSize = (float)TimeAndSalesRecord.BidSize * sc.MultiplierFromVolumeValueFormat(); if (BidSize< InVolumeMinFilter.GetInt() || (InVolumeMaxFilter.GetInt() > 0 && BidSize > InVolumeMaxFilter.GetInt() ) ) continue; --OutputArrayIndex; if (OutputArrayIndex < 0) break; FirstSubgraph[OutputArrayIndex] = BidSize; } else if (Flag == TIME_AND_SALES_STUDY_ASK_SIZE) // Ask size { float AskSize = (float)TimeAndSalesRecord.AskSize * sc.MultiplierFromVolumeValueFormat(); if (AskSize< InVolumeMinFilter.GetInt() || (InVolumeMaxFilter.GetInt() > 0 && AskSize > InVolumeMaxFilter.GetInt() ) ) continue; --OutputArrayIndex; if (OutputArrayIndex < 0) break; FirstSubgraph[OutputArrayIndex] = AskSize; } else if (Flag == TIME_AND_SALES_STUDY_TOTAL_BID_SIZE_DEPTH) { float TotalBidSizeDepth = (float)TimeAndSalesRecord.TotalBidDepth * sc.MultiplierFromVolumeValueFormat(); if (TotalBidSizeDepth < InVolumeMinFilter.GetInt() || (InVolumeMaxFilter.GetInt() > 0 && TotalBidSizeDepth > InVolumeMaxFilter.GetInt() ) ) continue; --OutputArrayIndex; if (OutputArrayIndex < 0) break; FirstSubgraph[OutputArrayIndex] = TotalBidSizeDepth; } else if (Flag == TIME_AND_SALES_STUDY_TOTAL_ASK_SIZE_DEPTH) { float TotalAskSizeDepth = (float)TimeAndSalesRecord.TotalAskDepth * sc.MultiplierFromVolumeValueFormat(); if (TotalAskSizeDepth < InVolumeMinFilter.GetInt() || (InVolumeMaxFilter.GetInt() > 0 && TotalAskSizeDepth > InVolumeMaxFilter.GetInt() ) ) continue; --OutputArrayIndex; if (OutputArrayIndex < 0) break; FirstSubgraph[OutputArrayIndex] = TotalAskSizeDepth; } else if (Flag == TIME_AND_SALES_STUDY_MILLISECONDS) // Milliseconds { --OutputArrayIndex; if (OutputArrayIndex < 0) break; FirstSubgraph[OutputArrayIndex] = (float)TimeAndSalesRecord.DateTime.GetMillisecond(); } } // Zero elements from the first index that was written to last time, to the // first index that was written to this time. for (int SubgraphIndex = 0; SubgraphIndex < sc.NumberOfArrays; ++SubgraphIndex) { for (int DataIndex = EarliestIndex; DataIndex < OutputArrayIndex; ++DataIndex) sc.Subgraph[SubgraphIndex][DataIndex] = 0.0f; } // Store the last index that was written to EarliestIndex = OutputArrayIndex; } /*==========================================================================*/ SCSFExport scsf_TimeAndSalesPrice(SCStudyInterfaceRef sc) { SCSubgraphRef Subgraph_Bid = sc.Subgraph[0]; SCSubgraphRef Subgraph_Ask = sc.Subgraph[1]; SCSubgraphRef Subgraph_Other = sc.Subgraph[2]; SCInputRef Input_VolumeFilterGE = sc.Input[2]; SCInputRef Input_VolumeFilterLE = sc.Input[3]; if (sc.SetDefaults) { // Set the configuration and defaults sc.GraphName = "Time and Sales Price"; sc.StudyDescription = ""; sc.GraphRegion = 1; sc.ValueFormat =VALUEFORMAT_INHERITED; Subgraph_Bid.Name = "Bid Trade"; Subgraph_Bid.DrawStyle = DRAWSTYLE_DASH; Subgraph_Bid.PrimaryColor = RGB(255,0,0); // Red Subgraph_Bid.LineWidth = 4; Subgraph_Bid.DrawZeros = false; Subgraph_Ask.Name = "Ask Trade"; Subgraph_Ask.DrawStyle = DRAWSTYLE_DASH; Subgraph_Ask.PrimaryColor = RGB(0,255,0); // Green Subgraph_Ask.LineWidth = 4; Subgraph_Ask.DrawZeros = false; Subgraph_Other.Name = "Other"; Subgraph_Other.DrawStyle = DRAWSTYLE_DASH; Subgraph_Other.PrimaryColor = RGB(255,255,255); // White Subgraph_Other.LineWidth = 4; Subgraph_Other.DrawZeros = false; Input_VolumeFilterGE.Name = "Volume Filter >="; Input_VolumeFilterGE.SetInt(1); Input_VolumeFilterGE.SetIntLimits(0, INT_MAX); Input_VolumeFilterLE.Name = "Volume Filter <= (0 means no limit)"; Input_VolumeFilterLE.SetInt(0); Input_VolumeFilterLE.SetIntLimits(0, INT_MAX); return; } TimeAndSales(sc, TIME_AND_SALES_STUDY_PRICE); } /*==========================================================================*/ SCSFExport scsf_TimeAndSalesVolume(SCStudyInterfaceRef sc) { SCSubgraphRef Subgraph_BidVol = sc.Subgraph[0]; SCSubgraphRef Subgraph_AskVol = sc.Subgraph[1]; SCSubgraphRef Subgraph_OtherVol = sc.Subgraph[2]; SCInputRef Input_VolumeFilterGreaterEqual = sc.Input[2]; SCInputRef Input_VolumeFilterLessEqual = sc.Input[3]; if (sc.SetDefaults) { // Set the configuration and defaults sc.GraphName = "Time and Sales Volume"; sc.StudyDescription = ""; sc.GraphRegion = 1; sc.ValueFormat = sc.VolumeValueFormat; Subgraph_BidVol.Name = "Bid Vol"; Subgraph_BidVol.DrawStyle = DRAWSTYLE_BAR; Subgraph_BidVol.PrimaryColor = RGB(255,0,0); // Red Subgraph_BidVol.LineWidth = 4; Subgraph_BidVol.DrawZeros = false; Subgraph_AskVol.Name = "Ask Vol"; Subgraph_AskVol.DrawStyle = DRAWSTYLE_BAR; Subgraph_AskVol.PrimaryColor = RGB(0,255,0); // Green Subgraph_AskVol.LineWidth = 4; Subgraph_AskVol.DrawZeros = false; Subgraph_OtherVol.Name = "Other Vol"; Subgraph_OtherVol.DrawStyle = DRAWSTYLE_BAR; Subgraph_OtherVol.PrimaryColor = RGB(255,255,255); // White Subgraph_OtherVol.LineWidth = 4; Subgraph_OtherVol.DrawZeros = false; Input_VolumeFilterGreaterEqual.Name = "Volume Filter >="; Input_VolumeFilterGreaterEqual.SetFloat(1); Input_VolumeFilterGreaterEqual.SetFloatLimits(0, FLT_MAX); Input_VolumeFilterLessEqual.Name = "Volume Filter <= (0 means no limit)"; Input_VolumeFilterLessEqual.SetFloat(0); Input_VolumeFilterLessEqual.SetFloatLimits(0, FLT_MAX); return; } TimeAndSales(sc, TIME_AND_SALES_STUDY_VOLUME); } /*==========================================================================*/ SCSFExport scsf_TimeAndSalesTime(SCStudyInterfaceRef sc) { SCSubgraphRef Subgraph_Time = sc.Subgraph[0]; SCInputRef Input_VolumeFilterGE = sc.Input[2]; SCInputRef Input_VolumeFilterLE = sc.Input[3]; if (sc.SetDefaults) { // Set the configuration and defaults sc.GraphName = "Time and Sales Time"; sc.StudyDescription = ""; sc.GraphRegion = 1; sc.ValueFormat = 20; // Time Subgraph_Time.Name = "Time"; Subgraph_Time.DrawStyle = DRAWSTYLE_LINE; Subgraph_Time.PrimaryColor = RGB(0,255,0); Subgraph_Time.DrawZeros = false; Input_VolumeFilterGE.Name = "Volume Filter >="; Input_VolumeFilterGE.SetInt(1); Input_VolumeFilterGE.SetIntLimits(0, INT_MAX); Input_VolumeFilterLE.Name = "Volume Filter <= (0 means no limit)"; Input_VolumeFilterLE.SetInt(0); Input_VolumeFilterLE.SetIntLimits(0, INT_MAX); return; } TimeAndSales(sc, TIME_AND_SALES_STUDY_TIME); } /*==========================================================================*/ SCSFExport scsf_TimeAndSalesBidAsk(SCStudyInterfaceRef sc) { SCSubgraphRef Subgraph_Bid = sc.Subgraph[0]; SCSubgraphRef Subgraph_Ask = sc.Subgraph[1]; if (sc.SetDefaults) { // Set the configuration and defaults sc.GraphName = "Time and Sales Bid & Ask"; sc.StudyDescription = ""; sc.GraphRegion = 1; sc.ValueFormat = VALUEFORMAT_INHERITED; Subgraph_Bid.Name = "Bid"; Subgraph_Bid.DrawStyle = DRAWSTYLE_LINE; Subgraph_Bid.PrimaryColor = RGB(255,0,0); // Red Subgraph_Bid.LineWidth = 1; Subgraph_Bid.LineLabel = LL_DISPLAY_VALUE | LL_VALUE_ALIGN_VALUES_SCALE | LL_VALUE_ALIGN_CENTER; Subgraph_Bid.DrawZeros = false; Subgraph_Ask.Name = "Ask"; Subgraph_Ask.DrawStyle = DRAWSTYLE_LINE; Subgraph_Ask.PrimaryColor = RGB(0,255,0); // Green Subgraph_Ask.LineWidth = 1; Subgraph_Ask.LineLabel = LL_DISPLAY_VALUE | LL_VALUE_ALIGN_VALUES_SCALE | LL_VALUE_ALIGN_CENTER; Subgraph_Ask.DrawZeros = false; return; } TimeAndSales(sc, TIME_AND_SALES_STUDY_BID_AND_ASK); } /*==========================================================================*/ SCSFExport scsf_TimeAndSalesBidSize(SCStudyInterfaceRef sc) { SCSubgraphRef Subgraph_BidSize = sc.Subgraph[0]; SCInputRef Input_VolumeFilterGreaterEqual = sc.Input[2]; SCInputRef Input_VolumeFilterLessEqual = sc.Input[3]; if (sc.SetDefaults) { // Set the configuration and defaults sc.GraphName = "Time and Sales Bid Size"; sc.GraphRegion = 1; sc.ValueFormat = sc.VolumeValueFormat; Subgraph_BidSize.Name = "Bid Size"; Subgraph_BidSize.DrawStyle = DRAWSTYLE_BAR; Subgraph_BidSize.PrimaryColor = RGB(255,0,0); // Red Subgraph_BidSize.LineWidth = 1; Subgraph_BidSize.DrawZeros = false; Input_VolumeFilterGreaterEqual.Name = "Size Filter >="; Input_VolumeFilterGreaterEqual.SetFloat(1); Input_VolumeFilterGreaterEqual.SetFloatLimits(0, FLT_MAX); Input_VolumeFilterLessEqual.Name = "Size Filter <= (0 means no limit)"; Input_VolumeFilterLessEqual.SetFloat(0); Input_VolumeFilterLessEqual.SetFloatLimits(0, FLT_MAX); return; } TimeAndSales(sc, TIME_AND_SALES_STUDY_BID_SIZE); } /*==========================================================================*/ SCSFExport scsf_TimeAndSalesAskSize(SCStudyInterfaceRef sc) { SCSubgraphRef Subgraph_AskSize = sc.Subgraph[0]; SCInputRef Input_VolumeFilterGreaterEqual = sc.Input[2]; SCInputRef Input_VolumeFilterLessEqual = sc.Input[3]; if (sc.SetDefaults) { // Set the configuration and defaults sc.GraphName = "Time and Sales Ask Size"; sc.GraphRegion = 1; sc.ValueFormat = sc.VolumeValueFormat; Subgraph_AskSize.Name = "Ask Size"; Subgraph_AskSize.DrawStyle = DRAWSTYLE_BAR; Subgraph_AskSize.PrimaryColor = RGB(0,255,0); // Green Subgraph_AskSize.LineWidth = 1; Subgraph_AskSize.DrawZeros = false; Input_VolumeFilterGreaterEqual.Name = "Size Filter >="; Input_VolumeFilterGreaterEqual.SetFloat(1); Input_VolumeFilterGreaterEqual.SetFloatLimits(0, FLT_MAX); Input_VolumeFilterLessEqual.Name = "Size Filter <= (0 means no limit)"; Input_VolumeFilterLessEqual.SetFloat(0); Input_VolumeFilterLessEqual.SetFloatLimits(0, FLT_MAX); return; } TimeAndSales(sc, TIME_AND_SALES_STUDY_ASK_SIZE); } /*==========================================================================*/ SCSFExport scsf_TimeAndSalesTotalAskSizeDepth(SCStudyInterfaceRef sc) { SCSubgraphRef Subgraph_TotalAskSizeDepth = sc.Subgraph[0]; SCInputRef Input_VolumeFilterGreaterEqual = sc.Input[2]; SCInputRef Input_VolumeFilterLessEqual = sc.Input[3]; if (sc.SetDefaults) { // Set the configuration and defaults sc.GraphName = "Time and Sales Total Ask Size Depth"; sc.GraphRegion = 1; sc.ValueFormat = sc.VolumeValueFormat; sc.UsesMarketDepthData = 1; Subgraph_TotalAskSizeDepth.Name = "Ask Size Depth"; Subgraph_TotalAskSizeDepth.DrawStyle = DRAWSTYLE_BAR; Subgraph_TotalAskSizeDepth.PrimaryColor = RGB(0,255,0); // Green Subgraph_TotalAskSizeDepth.LineWidth = 1; Subgraph_TotalAskSizeDepth.DrawZeros = false; Input_VolumeFilterGreaterEqual.Name = "Size Filter >="; Input_VolumeFilterGreaterEqual.SetFloat(1); Input_VolumeFilterGreaterEqual.SetFloatLimits(0, FLT_MAX); Input_VolumeFilterLessEqual.Name = "Size Filter <= (0 means no limit)"; Input_VolumeFilterLessEqual.SetFloat(0); Input_VolumeFilterLessEqual.SetFloatLimits(0, FLT_MAX); return; } TimeAndSales(sc, TIME_AND_SALES_STUDY_TOTAL_ASK_SIZE_DEPTH); } /*==========================================================================*/ SCSFExport scsf_TimeAndSalesTotalBidSizeDepth(SCStudyInterfaceRef sc) { SCSubgraphRef Subgraph_TotalBidSizeDepth = sc.Subgraph[0]; SCInputRef Input_VolumeFilterGreaterEqual = sc.Input[2]; SCInputRef Input_VolumeFilterLessEqual = sc.Input[3]; if (sc.SetDefaults) { // Set the configuration and defaults sc.GraphName = "Time and Sales Total Bid Size Depth"; sc.GraphRegion = 1; sc.ValueFormat = sc.VolumeValueFormat; sc.UsesMarketDepthData = 1; Subgraph_TotalBidSizeDepth.Name = "Bid Size Depth"; Subgraph_TotalBidSizeDepth.DrawStyle = DRAWSTYLE_BAR; Subgraph_TotalBidSizeDepth.PrimaryColor = RGB(255,0,0); // Green Subgraph_TotalBidSizeDepth.LineWidth = 1; Subgraph_TotalBidSizeDepth.DrawZeros = false; Input_VolumeFilterGreaterEqual.Name = "Size Filter >="; Input_VolumeFilterGreaterEqual.SetFloat(1); Input_VolumeFilterGreaterEqual.SetFloatLimits(0, FLT_MAX); Input_VolumeFilterLessEqual.Name = "Size Filter <= (0 means no limit)"; Input_VolumeFilterLessEqual.SetFloat(0); Input_VolumeFilterLessEqual.SetFloatLimits(0, FLT_MAX); return; } TimeAndSales(sc, TIME_AND_SALES_STUDY_TOTAL_BID_SIZE_DEPTH); } /*==========================================================================*/ SCSFExport scsf_TimeAndSalesMilliseconds(SCStudyInterfaceRef sc) { SCSubgraphRef Subgraph_MillisecondsSubgraph = sc.Subgraph[0]; if (sc.SetDefaults) { // Set the configuration and defaults sc.GraphName = "Time and Sales Milliseconds"; sc.StudyDescription = ""; sc.GraphRegion = 1; sc.ValueFormat = 0; Subgraph_MillisecondsSubgraph.Name = "Milliseconds"; Subgraph_MillisecondsSubgraph.DrawStyle = DRAWSTYLE_BAR; Subgraph_MillisecondsSubgraph.PrimaryColor = RGB(255,255,255); Subgraph_MillisecondsSubgraph.LineWidth = 4; Subgraph_MillisecondsSubgraph.DrawZeros = true; return; } TimeAndSales(sc, TIME_AND_SALES_STUDY_MILLISECONDS); } /*============================================================================ This study graphs a line for the selected Input Data item from another chart on to the chart this study is applied to. The data is synchronized so that the overlayed bars will match with the correct times. ----------------------------------------------------------------------------*/ SCSFExport scsf_OverlaySingleLine(SCStudyInterfaceRef sc) { SCSubgraphRef Subgraph_PriceOverlay = sc.Subgraph[0]; SCInputRef Input_InputData = sc.Input[0]; SCInputRef Input_ChartNumberToOverlay = sc.Input[3]; SCInputRef Input_Multiplier = sc.Input[4]; SCInputRef Input_DrawZeroValues = sc.Input[5]; // Set configuration variables if (sc.SetDefaults) { sc.GraphName = "Overlay (Single Line)"; sc.ValueFormat = VALUEFORMAT_INHERITED; sc.GraphRegion = 1; sc.ScaleRangeType = SCALE_INDEPENDENT; Subgraph_PriceOverlay.Name = "Price Overlay"; Subgraph_PriceOverlay.DrawStyle = DRAWSTYLE_LINE; Subgraph_PriceOverlay.PrimaryColor = RGB(0,255,0); Subgraph_PriceOverlay.DrawZeros = false; Input_InputData.Name = "Input Data"; Input_InputData.SetInputDataIndex(SC_LAST); Input_ChartNumberToOverlay.Name = "Chart Number To Overlay"; Input_ChartNumberToOverlay.SetChartNumber(2); Input_Multiplier.Name = "Multiplier"; Input_Multiplier.SetFloat(1.0f); Input_DrawZeroValues.Name = "Draw Zero Values"; Input_DrawZeroValues.SetYesNo(false); sc.AutoLoop = 1; return; } // Do data processing Subgraph_PriceOverlay.DrawZeros = Input_DrawZeroValues.GetYesNo(); // Get the array for the requested Input Data from the requested chart SCFloatArray PriceArray; sc.GetChartArray(-Input_ChartNumberToOverlay.GetChartNumber(), Input_InputData.GetInputDataIndex(), PriceArray); // Make sure we got something if (PriceArray.GetArraySize() == 0) return; int TheirIndex = sc.GetNearestMatchForDateTimeIndex(Input_ChartNumberToOverlay.GetChartNumber(), sc.Index); Subgraph_PriceOverlay[sc.Index] = PriceArray[TheirIndex] * Input_Multiplier.GetFloat(); SCString ChartOverlayName = sc.GetStudyNameFromChart(Input_ChartNumberToOverlay.GetChartNumber(), 0); sc.GraphName.Format("%s Overlay", ChartOverlayName.GetChars()); } /*==========================================================================*/ SCSFExport scsf_UseToolExampleDrawingPitchfork(SCStudyInterfaceRef sc) { // Pitchfork example // Set configuration variables if (sc.SetDefaults) { sc.GraphName = "UseTool Example: Pitchfork"; sc.StudyDescription = ""; sc.GraphRegion = 0; sc.AutoLoop = 0; //No automatic looping return; } s_UseTool Tool; Tool.ChartNumber = sc.ChartNumber; Tool.DrawingType = DRAWING_PITCHFORK; int& r_LineNumber = sc.GetPersistentInt(1); if(r_LineNumber != 0) Tool.LineNumber = r_LineNumber; int BarIndex = max(0, sc.ArraySize - 50); //Beginning of middle line Tool.BeginDateTime = sc.BaseDateTimeIn[BarIndex]; Tool.BeginValue = sc.Close[BarIndex]; //Top line Tool.EndDateTime = sc.BaseDateTimeIn[BarIndex+10]; Tool.EndValue = sc.High[BarIndex]; //Bottom line Tool.ThirdDateTime = sc.BaseDateTimeIn[BarIndex+10]; Tool.ThirdValue = sc.Low[BarIndex]; Tool.Color = RGB(0,200,0); Tool.LineWidth = 2; Tool.RetracementLevels[0] = 100.0f; Tool.RetracementLevels[1] = -100.0f; Tool.RetracementLevels[2] = 150.0f; Tool.RetracementLevels[3] = -150.0f; Tool.LevelColor[2] = COLOR_YELLOW; Tool.LevelColor[3] = COLOR_MAGENTA; Tool.AddMethod = UTAM_ADD_OR_ADJUST; sc.UseTool(Tool); r_LineNumber = Tool.LineNumber;//Remember line number which has been automatically set } /*==========================================================================*/ SCSFExport scsf_UseToolExampleDrawingMarker(SCStudyInterfaceRef sc) { // Set configuration variables if (sc.SetDefaults) { sc.GraphName = "UseTool Example: Marker"; sc.StudyDescription = ""; sc.GraphRegion = 0; sc.AutoLoop = 0; //No automatic looping return; } // Do data processing for (int BarIndex = sc.UpdateStartIndex; BarIndex < sc.ArraySize - 1; ++BarIndex) { //Since the AddMethod = UTAM_ADD_ALWAYS, we do not want to add a marker drawing on the last bar until it is completed. The loop indexing above prevents this, but we also have added this as an extra check. if (sc.GetBarHasClosedStatus(BarIndex) != BHCS_BAR_HAS_CLOSED) return; if(BarIndex % 5) continue; s_UseTool Tool; Tool.ChartNumber = sc.ChartNumber; //Tool.LineNumber will be automatically set. No need to set this. Tool.DrawingType = DRAWING_MARKER; Tool.BeginIndex = BarIndex; if(BarIndex % 10 == 0) { Tool.MarkerType = MARKER_ARROWUP; Tool.BeginValue = sc.Low[BarIndex]; } else { Tool.MarkerType = MARKER_ARROWDOWN; Tool.BeginValue = sc.High[BarIndex]; } Tool.Region = 0; Tool.Color = RGB(255, 255, 0); Tool.MarkerSize = 8; Tool.LineWidth = 5; Tool.AddMethod = UTAM_ADD_ALWAYS; sc.UseTool(Tool); // Here we make the function call to add the marker } } /*==========================================================================*/ SCSFExport scsf_UseToolExampleDrawingLine(SCStudyInterfaceRef sc) { // Set configuration variables if (sc.SetDefaults) { sc.GraphName = "UseTool Example: Line"; sc.GraphRegion = 0; sc.AutoLoop = 0; //No automatic looping return; } int& r_LineNumber = sc.GetPersistentInt(1); if (sc.IsFullRecalculation) { //Draw vertical line on prior bar during full recalculation. s_UseTool Tool; Tool.Clear(); Tool.ChartNumber = sc.ChartNumber; //Tool.LineNumber will be automatically set. No need to set this. Tool.DrawingType = DRAWING_LINE; int DrawingIndex = sc.ArraySize - 1; Tool.BeginDateTime = sc.BaseDateTimeIn[DrawingIndex-20]; Tool.EndDateTime = sc.BaseDateTimeIn[DrawingIndex]; Tool.BeginValue = sc.Low[DrawingIndex]; Tool.EndValue = sc.High[DrawingIndex]; Tool.Text = "Label 1"; Tool.TextAlignment = DT_BOTTOM | DT_RIGHT; Tool.Region = 0; Tool.Color = RGB(255, 255, 0); Tool.LineWidth = 5; Tool.AddMethod = UTAM_ADD_ALWAYS; sc.UseTool(Tool); r_LineNumber = Tool.LineNumber; } else if (sc.UpdateStartIndex < sc.ArraySize -1) { //Now move the drawing to the last bar when a new bar has been added to the chart s_UseTool Tool; Tool.Clear(); Tool.ChartNumber = sc.ChartNumber; int DrawingIndex = sc.ArraySize - 1; Tool.BeginDateTime = sc.BaseDateTimeIn[DrawingIndex]; Tool.EndDateTime = sc.BaseDateTimeIn[DrawingIndex]; Tool.BeginValue = sc.Low[DrawingIndex]; Tool.EndValue = sc.High[DrawingIndex]; Tool.AddMethod = UTAM_ADD_OR_ADJUST; Tool.LineNumber = r_LineNumber; sc.UseTool(Tool); } //int Count = sc.DeleteACSChartDrawing(sc.ChartNumber, TOOL_DELETE_ALL, 0); } /*==========================================================================*/ SCSFExport scsf_UseToolExampleDrawingPriceRetracement(SCStudyInterfaceRef sc) { // Set configuration variables if (sc.SetDefaults) { sc.GraphName = "UseTool Example: Price Retracement"; sc.GraphRegion = 0; sc.AutoLoop = 0; //No automatic looping return; } int& r_LineNumber = sc.GetPersistentInt(1); if (sc.IsFullRecalculation) { s_UseTool Tool; //Tool.Clear(); Tool.ChartNumber = sc.ChartNumber; Tool.DrawingType = DRAWING_RETRACEMENT; Tool.ExtendLeft = 1;// Extend the horizontal retracement lines to the left of the chart region. if (r_LineNumber != 0) Tool.LineNumber = r_LineNumber; // Update BarIndex to 40 bars from the end int BarIndex = sc.ArraySize - 100;// 100 bars back and from high to low BarIndex = max(BarIndex, 0); Tool.BeginDateTime = sc.BaseDateTimeIn[BarIndex]; Tool.EndDateTime = sc.BaseDateTimeIn[sc.ArraySize - 1]; Tool.BeginValue = sc.High[sc.ArraySize - 1]; Tool.EndValue = sc.Low[BarIndex]; Tool.Color = RGB(255, 0, 255); // Magenta Tool.AddMethod = UTAM_ADD_OR_ADJUST; for (int LevelIndex = 0; LevelIndex < 16; LevelIndex++) Tool.RetracementLevels[LevelIndex] = LevelIndex * 10.0f; Tool.ShowPrice = 1; Tool.ShowPercent = 1; Tool.RoundToTickSize = 0; Tool.TextAlignment = DT_VCENTER; // label vertical alignment sc.UseTool(Tool); r_LineNumber = Tool.LineNumber;//Remember line number which has been automatically set } else if (sc.UpdateStartIndex < sc.ArraySize - 1) { //Now move the drawing to the last bar when a new bar has been added to the chart s_UseTool Tool; //Tool.Clear(); Tool.RetracementLevels[10] = FLT_MAX; Tool.ChartNumber = sc.ChartNumber; Tool.AddMethod = UTAM_ADD_OR_ADJUST; Tool.LineNumber = r_LineNumber; sc.UseTool(Tool); } } /*==========================================================================*/ SCSFExport scsf_UseToolExampleDrawingPriceExpansion(SCStudyInterfaceRef sc) { // Set configuration variables if (sc.SetDefaults) { sc.GraphName = "UseTool Example: Price Expansion"; sc.GraphRegion = 0; sc.AutoLoop = 0; //No automatic looping return; } int& r_LineNumber = sc.GetPersistentInt(1); if (sc.IsFullRecalculation) { s_UseTool Tool; //Tool.Clear(); Tool.ChartNumber = sc.ChartNumber; Tool.DrawingType = DRAWING_PRICE_EXPANSION; Tool.ExtendLeft = 1;// Extend the horizontal lines to the left of the chart region. if (r_LineNumber != 0) Tool.LineNumber = r_LineNumber; // Update BarIndex to 40 bars from the end int BarIndex = sc.ArraySize - 100;// 100 bars back and from high to low BarIndex = max(BarIndex, 0); Tool.BeginDateTime = sc.BaseDateTimeIn[BarIndex]; Tool.EndDateTime = sc.BaseDateTimeIn[BarIndex];//sc.ArraySize - 1 Tool.BeginValue = sc.High[BarIndex];//sc.ArraySize - 1 Tool.EndValue = sc.Low[BarIndex]; Tool.Color = RGB(255, 0, 255); // Magenta Tool.AddMethod = UTAM_ADD_OR_ADJUST; for (int LevelIndex = 0; LevelIndex < min(8, ACSIL_DRAWING_MAX_LEVELS); LevelIndex++) Tool.RetracementLevels[LevelIndex] = LevelIndex * 10.0f; Tool.ShowPrice = 1; Tool.ShowPercent = 1; Tool.RoundToTickSize = 0; Tool.TextAlignment = DT_VCENTER; // label vertical alignment sc.UseTool(Tool); r_LineNumber = Tool.LineNumber;//Remember line number which has been automatically set } } /*==========================================================================*/ SCSFExport scsf_UseToolExampleDrawingRay(SCStudyInterfaceRef sc) { // Set configuration variables if (sc.SetDefaults) { sc.GraphName = "UseTool Example: Ray"; sc.GraphRegion = 0; sc.AutoLoop = 0; //No automatic looping return; } // Do data processing int BarIndex; int& r_LineNumber = sc.GetPersistentInt(1); s_UseTool Tool; //Draw chart drawing on chart study is applied to. It is not possible to draw on another chart unless Tool.AddAsUserDrawnDrawing is set to 1. Tool.ChartNumber = sc.ChartNumber; //Tool.AddAsUserDrawnDrawing = 1; Tool.DrawingType = DRAWING_RAY; //int &LineNumber2 = sc.GetPersistentInt(2); if (r_LineNumber != 0) Tool.LineNumber = r_LineNumber; // Set BarIndex to 10 bars from the end BarIndex = sc.ArraySize - 10; BarIndex = max(BarIndex, 0); Tool.BeginDateTime = sc.BaseDateTimeIn[BarIndex]; Tool.EndDateTime = sc.BaseDateTimeIn[sc.ArraySize - 1]; Tool.BeginValue = sc.Low[BarIndex]; Tool.EndValue = sc.High[sc.ArraySize - 1]; Tool.Region = 0; Tool.Color = RGB(0, 0, 255); Tool.AddMethod = UTAM_ADD_OR_ADJUST; sc.UseTool(Tool); // Here we make the function call to add the line r_LineNumber = Tool.LineNumber;//Remember line number which has been automatically set } /*==========================================================================*/ SCSFExport scsf_UseToolExampleDrawingText30BarsBack(SCStudyInterfaceRef sc) { // Text example, put 30 bars back // Set configuration variables if (sc.SetDefaults) { sc.GraphName = "UseTool Example: Text 30 Bars Back"; sc.GraphRegion = 0; sc.AutoLoop = 0; //No automatic looping return; } // Do data processing int BarIndex; int& r_LineNumber = sc.GetPersistentInt(1); s_UseTool Tool; Tool.ChartNumber = sc.ChartNumber; Tool.DrawingType = DRAWING_TEXT; //int &LineNumber3 = sc.GetPersistentInt(3); if (r_LineNumber != 0) Tool.LineNumber = r_LineNumber; // Set BarIndex to 30 bars from the end BarIndex = sc.ArraySize - 30; BarIndex = max(BarIndex, 0); Tool.BeginDateTime = sc.BaseDateTimeIn[BarIndex]; Tool.BeginValue = sc.Low[BarIndex]; Tool.Color = RGB(255, 255, 0); // Yellow Tool.Text = "Text Example"; Tool.FontSize = 16; Tool.AddMethod = UTAM_ADD_OR_ADJUST; sc.UseTool(Tool); r_LineNumber = Tool.LineNumber;//Remember line number which has been automatically set } /*==========================================================================*/ SCSFExport scsf_UseToolExampleDrawingVerticalLine(SCStudyInterfaceRef sc) { // Draws a vertical line 20 bars back. // Set configuration variables if (sc.SetDefaults) { sc.GraphName = "UseTool Example: Vertical Line"; sc.GraphRegion = 0; sc.AutoLoop = 0; //No automatic looping return; } // Do data processing int BarIndex; int& r_LineNumber = sc.GetPersistentInt(1); s_UseTool Tool; Tool.ChartNumber = sc.ChartNumber; Tool.DrawingType = DRAWING_VERTICALLINE; //int &LineNumber5 = sc.GetPersistentInt(5); if (r_LineNumber != 0) Tool.LineNumber = r_LineNumber; // Update BarIndex to 20 bars from the end BarIndex = sc.ArraySize - 20; BarIndex = max(BarIndex, 0); Tool.BeginDateTime = sc.BaseDateTimeIn[BarIndex]; Tool.Color = RGB(255, 0, 0); // Red Tool.AddMethod = UTAM_ADD_OR_ADJUST; sc.UseTool(Tool); r_LineNumber = Tool.LineNumber;//Remember line number which has been automatically set // If the vertical line exists, add a message to the Message Log if (sc.ChartDrawingExists(sc.ChartNumber, Tool.LineNumber)) { sc.AddMessageToLog("Vertical line exists.", 0); } } /*==========================================================================*/ SCSFExport scsf_UseToolExampleDrawingTextFillSpace(SCStudyInterfaceRef sc) { // Display some text in the fill space // Set configuration variables if (sc.SetDefaults) { sc.GraphName = "UseTool Example: Text Fill Space"; sc.GraphRegion = 0; sc.AutoLoop = 0; //No automatic looping return; } int& r_LineNumber = sc.GetPersistentInt(1); s_UseTool Tool; Tool.ChartNumber = sc.ChartNumber; Tool.DrawingType = DRAWING_TEXT; //int &LineNumber6 = sc.GetPersistentInt(6); if (r_LineNumber != 0) Tool.LineNumber = r_LineNumber; Tool.BeginDateTime = -1; Tool.BeginValue = sc.Low[sc.ArraySize - 1]; Tool.Color = COLOR_WHITE; Tool.Text = "Minus 1"; Tool.AddMethod = UTAM_ADD_OR_ADJUST; sc.UseTool(Tool); r_LineNumber = Tool.LineNumber;//Remember line number which has been automatically set } /*==========================================================================*/ SCSFExport scsf_UseToolExampleDrawingMinus1(SCStudyInterfaceRef sc) { // Set configuration variables if (sc.SetDefaults) { sc.GraphName = "UseTool Example: Minus 1"; sc.GraphRegion = 0; sc.AutoLoop = 0; //No automatic looping return; } int& r_LineNumber = sc.GetPersistentInt(1); s_UseTool Tool; Tool.ChartNumber = sc.ChartNumber; Tool.LineNumber = r_LineNumber; Tool.Color = COLOR_CYAN; Tool.Text = "Minus 1 - Changed"; Tool.AddMethod = UTAM_ADD_OR_ADJUST; sc.UseTool(Tool); r_LineNumber = Tool.LineNumber; } /*==========================================================================*/ SCSFExport scsf_UseToolExampleDrawingTextAtTheEndOfTheChart(SCStudyInterfaceRef sc) { // Display some text after the end of the chart // Set configuration variables if (sc.SetDefaults) { sc.GraphName = "UseTool Example: Text At The End Of The Chart"; sc.GraphRegion = 0; sc.AutoLoop = 0; //No automatic looping return; } // Do data processing int BarIndex; int& r_LineNumber = sc.GetPersistentInt(1); s_UseTool Tool; Tool.ChartNumber = sc.ChartNumber; Tool.DrawingType = DRAWING_TEXT; //int &LineNumber7 = sc.GetPersistentInt(7); if (r_LineNumber != 0) Tool.LineNumber = r_LineNumber; Tool.BeginDateTime = -2; // Update BarIndex to 20 bars from the end BarIndex = sc.ArraySize - 20; BarIndex = max(BarIndex, 0); Tool.BeginValue = sc.Low[BarIndex]; Tool.Color = RGB(255, 255, 255); // White; Tool.Text = "Minus 2"; Tool.AddMethod = UTAM_ADD_OR_ADJUST; Tool.ReverseTextColor = 1; // true sc.UseTool(Tool); r_LineNumber = Tool.LineNumber;//Remember line number which has been automatically set } /*==========================================================================*/ SCSFExport scsf_UseToolExampleDrawingArrow(SCStudyInterfaceRef sc) { // Add an arrow // Set configuration variables if (sc.SetDefaults) { sc.GraphName = "UseTool Example: Arrow"; sc.GraphRegion = 0; sc.AutoLoop = 0; //No automatic looping return; } // Do data processing int BarIndex; int& r_LineNumber = sc.GetPersistentInt(1); s_UseTool Tool; Tool.ChartNumber = sc.ChartNumber; Tool.DrawingType = DRAWING_ARROW; //int &LineNumber8 = sc.GetPersistentInt(8); if (r_LineNumber != 0) Tool.LineNumber = r_LineNumber; // Update BarIndex to 30 bars from the end BarIndex = sc.ArraySize - 30; BarIndex = max(BarIndex, 0); Tool.BeginDateTime = sc.BaseDateTimeIn[BarIndex]; Tool.EndDateTime = sc.BaseDateTimeIn[sc.ArraySize - 11]; Tool.BeginValue = sc.Low[BarIndex + 10]; Tool.EndValue = sc.High[sc.ArraySize - 1]; Tool.Color = RGB(255, 255, 0); // Yellow Tool.AddMethod = UTAM_ADD_OR_ADJUST; Tool.ArrowHeadSize = 5.0; // ratio when not fixed Tool.FixedSizeArrowHead = 0; sc.UseTool(Tool); r_LineNumber = Tool.LineNumber;//Remember line number which has been automatically set } /*==========================================================================*/ SCSFExport scsf_UseToolExampleDrawingHorizontalLineLastPrice(SCStudyInterfaceRef sc) { // Draw a horizontal line at the last price. // Set configuration variables if (sc.SetDefaults) { sc.GraphName = "UseTool Example: Horizontal Line Last Price"; sc.GraphRegion = 0; sc.AutoLoop = 0; //No automatic looping return; } int& r_LineNumber = sc.GetPersistentInt(1); s_UseTool Tool; Tool.ChartNumber = sc.ChartNumber; Tool.DrawingType = DRAWING_HORIZONTALLINE; Tool.DisplayHorizontalLineValue = 1; //int &LineNumber9 = sc.GetPersistentInt(9); if (r_LineNumber != 0) Tool.LineNumber = r_LineNumber; Tool.BeginValue = sc.Close[sc.ArraySize - 1]; Tool.Color = RGB(255, 0, 255); // Magenta Tool.LineWidth = 4; Tool.AddMethod = UTAM_ADD_OR_ADJUST; sc.UseTool(Tool); r_LineNumber = Tool.LineNumber;//Remember line number which has been automatically set } /*==========================================================================*/ SCSFExport scsf_UseToolExampleDrawingHorizontalLineAtLowOfLast30Bars(SCStudyInterfaceRef sc) { // Draw a horizontal line at the low of the last 30 bars. // Set configuration variables if (sc.SetDefaults) { sc.GraphName = "UseTool Example: Horizontal Line At Low Of Last 30 Bars"; sc.GraphRegion = 0; sc.AutoLoop = 0; //No automatic looping return; } // Do data processing int BarIndex; int& r_LineNumber = sc.GetPersistentInt(1); s_UseTool Tool; Tool.ChartNumber = sc.ChartNumber; Tool.DrawingType = DRAWING_HORIZONTALLINE; //int &LineNumber10 = sc.GetPersistentInt(10); if (r_LineNumber != 0) Tool.LineNumber = r_LineNumber; // Update BarIndex to 30 bars from the end BarIndex = sc.ArraySize - 30; BarIndex = max(BarIndex, 0); Tool.BeginValue = sc.GetLowest(sc.Low, sc.ArraySize - 1, sc.ArraySize - BarIndex); Tool.Color = RGB(127, 0, 255); // Purple Tool.LineWidth = 1; // LineWidth must be 1 to use non-solid line styles Tool.LineStyle = LINESTYLE_DOT; Tool.AddMethod = UTAM_ADD_OR_ADJUST; sc.UseTool(Tool); r_LineNumber = Tool.LineNumber;//Remember line number which has been automatically set } /*==========================================================================*/ SCSFExport scsf_UseToolExampleDrawingText40BarsBack(SCStudyInterfaceRef sc) { // Numbers as text example. Put 40 bars back // Set configuration variables if (sc.SetDefaults) { sc.GraphName = "UseTool Example: Text 40 Bars Back"; sc.GraphRegion = 0; sc.AutoLoop = 0; //No automatic looping return; } // Do data processing int BarIndex; int& r_LineNumber = sc.GetPersistentInt(1); s_UseTool Tool; Tool.ChartNumber = sc.ChartNumber; Tool.DrawingType = DRAWING_TEXT; //int &LineNumber11 = sc.GetPersistentInt(11); if (r_LineNumber != 0) Tool.LineNumber = r_LineNumber; // Update BarIndex to 40 bars from the end BarIndex = sc.ArraySize - 40; BarIndex = max(BarIndex, 0); Tool.BeginDateTime = sc.BaseDateTimeIn[BarIndex]; Tool.BeginValue = sc.High[BarIndex]; Tool.Color = RGB(255, 255, 0); // Yellow Tool.Text.Format("High Value: %.3f", sc.High[BarIndex]); Tool.AddMethod = UTAM_ADD_OR_ADJUST; sc.UseTool(Tool); r_LineNumber = Tool.LineNumber;//Remember line number which has been automatically set } /*==========================================================================*/ SCSFExport scsf_UseToolExampleChangeFontBackColor(SCStudyInterfaceRef sc) { // Change font back color // Set configuration variables if (sc.SetDefaults) { sc.GraphName = "UseTool Example: Change Font Back Color"; sc.GraphRegion = 0; sc.AutoLoop = 0; //No automatic looping return; } int& r_LineNumber = sc.GetPersistentInt(1); s_UseTool Tool; Tool.ChartNumber = sc.ChartNumber; Tool.LineNumber = r_LineNumber; Tool.FontBackColor = RGB(255, 255, 255); Tool.AddMethod = UTAM_ADD_OR_ADJUST; sc.UseTool(Tool); r_LineNumber = Tool.LineNumber; } /*==========================================================================*/ SCSFExport scsf_UseToolExampleChangeFontColorBackToTransparent(SCStudyInterfaceRef sc) { // Change font back color back to transparent // Set configuration variables if (sc.SetDefaults) { sc.GraphName = "UseTool Example: Change Font Color Back To Transparent"; sc.GraphRegion = 0; sc.AutoLoop = 0; //No automatic looping return; } int& r_LineNumber = sc.GetPersistentInt(1); s_UseTool Tool; Tool.ChartNumber = sc.ChartNumber; Tool.LineNumber = r_LineNumber; Tool.TransparentLabelBackground = 1; Tool.AddMethod = UTAM_ADD_OR_ADJUST; sc.UseTool(Tool); r_LineNumber = Tool.LineNumber; } /*==========================================================================*/ SCSFExport scsf_UseToolExampleRectangleHighlight(SCStudyInterfaceRef sc) { // Draw a rectangle highlight // Set configuration variables if (sc.SetDefaults) { sc.GraphName = "UseTool Example: Rectangle Highlight"; sc.GraphRegion = 0; sc.AutoLoop = 0; //No automatic looping return; } // Do data processing int BarIndex; int& r_LineNumber = sc.GetPersistentInt(1); s_UseTool Tool; Tool.ChartNumber = sc.ChartNumber; Tool.DrawingType = DRAWING_RECTANGLEHIGHLIGHT; //int &LineNumber12 = sc.GetPersistentInt(12); if (r_LineNumber != 0) Tool.LineNumber = r_LineNumber; // Update BarIndex to 30 bars from the end BarIndex = max(sc.ArraySize - 25, 0); Tool.BeginDateTime = sc.BaseDateTimeIn[BarIndex]; BarIndex = max(sc.ArraySize - 15, 0); Tool.EndDateTime = sc.BaseDateTimeIn[BarIndex]; Tool.BeginValue = sc.GetHighest(sc.Low, BarIndex, 10); Tool.EndValue = sc.GetLowest(sc.Low, BarIndex, 10); Tool.Color = RGB(255, 0, 0); // Red Tool.LineWidth = 1; //To see the outline this must be 1 or greater. Tool.SecondaryColor = RGB(0, 255, 0); Tool.TransparencyLevel = 50; Tool.AddMethod = UTAM_ADD_OR_ADJUST; sc.UseTool(Tool); r_LineNumber = Tool.LineNumber;//Remember line number which has been automatically set } /*==========================================================================*/ SCSFExport scsf_UseToolExampleChangeRectagleHighlight(SCStudyInterfaceRef sc) { // Change rectangle highlight // Set configuration variables if (sc.SetDefaults) { sc.GraphName = "UseTool Example: Change Rectangle Highlight"; sc.GraphRegion = 0; sc.AutoLoop = 0; //No automatic looping return; } int& r_LineNumber = sc.GetPersistentInt(1); s_UseTool Tool; Tool.ChartNumber = sc.ChartNumber; Tool.LineNumber = r_LineNumber; Tool.Color = RGB(255, 200, 0); Tool.LineWidth = 3; Tool.SecondaryColor = RGB(0, 0, 255); Tool.AddMethod = UTAM_ADD_OR_ADJUST; sc.UseTool(Tool); r_LineNumber = Tool.LineNumber; } /*==========================================================================*/ SCSFExport scsf_UseToolExampleDrawingPriceProjection(SCStudyInterfaceRef sc) { // Custom Projection levels example // 60 bars back and from high to low, project from 40 bars back // Set configuration variables if (sc.SetDefaults) { sc.GraphName = "UseTool Example: Custom Projection Levels"; sc.GraphRegion = 0; sc.AutoLoop = 0; //No automatic looping return; } // Do data processing int BarIndex; int& r_LineNumber = sc.GetPersistentInt(1); s_UseTool Tool; Tool.ChartNumber = sc.ChartNumber; Tool.DrawingType = DRAWING_PRICE_PROJECTION; //int &LineNumber13 = sc.GetPersistentInt(13); if (r_LineNumber != 0) Tool.LineNumber = r_LineNumber; // Update BarIndex to 60 bars from the end BarIndex = sc.ArraySize - 60; BarIndex = max(BarIndex, 0); Tool.BeginDateTime = sc.BaseDateTimeIn[BarIndex]; Tool.BeginValue = sc.High[BarIndex]; BarIndex = sc.ArraySize - 50; BarIndex = max(BarIndex, 0); Tool.EndDateTime = sc.BaseDateTimeIn[BarIndex]; Tool.EndValue = sc.Low[BarIndex]; BarIndex = sc.ArraySize - 40; BarIndex = max(BarIndex, 0); Tool.ThirdDateTime = sc.BaseDateTimeIn[BarIndex]; Tool.ThirdValue = sc.High[BarIndex]; Tool.Color = COLOR_LIGHTSTEELBLUE; Tool.AddMethod = UTAM_ADD_OR_ADJUST; for (int LevelIndex = 0; LevelIndex < 16; LevelIndex++) Tool.RetracementLevels[LevelIndex] = LevelIndex * 10.0f; sc.UseTool(Tool); r_LineNumber = Tool.LineNumber;//Remember line number which has been automatically set } /*==========================================================================*/ SCSFExport scsf_UseToolExampleDrawingPitchforkV2(SCStudyInterfaceRef sc) { // Pitchfork example // Set configuration variables if (sc.SetDefaults) { sc.GraphName = "UseTool Example: Pitchfork V2"; sc.GraphRegion = 0; sc.AutoLoop = 0; //No automatic looping return; } // Do data processing int BarIndex; int& r_LineNumber = sc.GetPersistentInt(1); s_UseTool Tool; Tool.ChartNumber = sc.ChartNumber; Tool.DrawingType = DRAWING_PITCHFORK; //int &LineNumber14 = sc.GetPersistentInt(14); if (r_LineNumber != 0) Tool.LineNumber = r_LineNumber; BarIndex = max(0, sc.ArraySize - 50); //Beginning of middle line Tool.BeginDateTime = sc.BaseDateTimeIn[BarIndex]; Tool.BeginValue = sc.Close[BarIndex]; //Beginning of top line Tool.EndDateTime = sc.BaseDateTimeIn[BarIndex]; Tool.EndValue = sc.High[BarIndex]; //Beginning of bottom line Tool.ThirdDateTime = sc.BaseDateTimeIn[BarIndex]; Tool.ThirdValue = sc.Low[BarIndex]; Tool.Color = RGB(0, 200, 0); Tool.LineWidth = 5; Tool.AddMethod = UTAM_ADD_OR_ADJUST; Tool.RetracementLevels[0] = 100.0f; Tool.RetracementLevels[1] = -100.0f; Tool.RetracementLevels[2] = 150.0f; Tool.RetracementLevels[3] = -150.0f; Tool.LevelColor[2] = COLOR_YELLOW; Tool.LevelColor[3] = COLOR_MAGENTA; sc.UseTool(Tool); r_LineNumber = Tool.LineNumber;//Remember line number which has been automatically set } /*==========================================================================*/ SCSFExport scsf_UseToolExampleDrawingParallelLines(SCStudyInterfaceRef sc) { // Parallel lines example // Set configuration variables if (sc.SetDefaults) { sc.GraphName = "UseTool Example: Parallel Lines"; sc.GraphRegion = 0; sc.AutoLoop = 0; //No automatic looping return; } // Do data processing int BarIndex; int& r_LineNumber = sc.GetPersistentInt(1); s_UseTool Tool; Tool.ChartNumber = sc.ChartNumber; Tool.DrawingType = DRAWING_PARALLEL_LINES; //int &LineNumber15 = sc.GetPersistentInt(15); if (r_LineNumber != 0) Tool.LineNumber = r_LineNumber; BarIndex = max(0, sc.ArraySize - 90); Tool.BeginDateTime = sc.BaseDateTimeIn[BarIndex]; Tool.BeginValue = sc.High[BarIndex]; BarIndex = max(0, sc.ArraySize - 70); Tool.EndDateTime = sc.BaseDateTimeIn[BarIndex]; Tool.EndValue = sc.High[BarIndex]; BarIndex = max(0, sc.ArraySize - 80); Tool.ThirdDateTime = sc.BaseDateTimeIn[BarIndex]; Tool.ThirdValue = sc.Low[BarIndex]; Tool.Color = RGB(128, 0, 0); Tool.AddMethod = UTAM_ADD_OR_ADJUST; Tool.RetracementLevels[0] = 200.0f; Tool.RetracementLevels[1] = -200.0f; Tool.LevelColor[0] = COLOR_GOLDENROD; Tool.LevelColor[1] = COLOR_GOLDENROD; sc.UseTool(Tool); r_LineNumber = Tool.LineNumber;//Remember line number which has been automatically set } /*==========================================================================*/ SCSFExport scsf_UseToolExampleDrawingLinearRegression(SCStudyInterfaceRef sc) { // Linear Regression example // Set configuration variables if (sc.SetDefaults) { sc.GraphName = "UseTool Example: Linear Regression"; sc.GraphRegion = 0; sc.AutoLoop = 0; //No automatic looping return; } // Do data processing int BarIndex; int& r_LineNumber = sc.GetPersistentInt(1); s_UseTool Tool; Tool.ChartNumber = sc.ChartNumber; Tool.DrawingType = DRAWING_LINEAR_REGRESSION; //int &LineNumber16 = sc.GetPersistentInt(16); if (r_LineNumber != 0) Tool.LineNumber = r_LineNumber; BarIndex = max(0, sc.ArraySize - 90); Tool.BeginDateTime = sc.BaseDateTimeIn[BarIndex]; Tool.BeginValue = sc.Open[BarIndex]; BarIndex = max(0, sc.ArraySize - 60); Tool.EndDateTime = sc.BaseDateTimeIn[BarIndex]; Tool.EndValue = sc.Open[BarIndex]; Tool.Color = RGB(0, 128, 0); Tool.LineWidth = 3; Tool.AddMethod = UTAM_ADD_ONLY_IF_NEW;// UTAM_ADD_OR_ADJUST; Tool.RetracementLevels[0] = 2.0f; Tool.RetracementLevels[1] = -2.0f; Tool.RetracementLevels[2] = 3.0f; Tool.RetracementLevels[3] = -3.0f; Tool.LevelColor[0] = COLOR_GOLDENROD; Tool.LevelColor[1] = COLOR_GOLDENROD; Tool.ExtendRight = 1; sc.UseTool(Tool); r_LineNumber = Tool.LineNumber;//Remember line number which has been automatically set } /*==========================================================================*/ SCSFExport scsf_UseToolExampleDrawingTimeExpansion(SCStudyInterfaceRef sc) { // Time Expansion example // Set configuration variables if (sc.SetDefaults) { sc.GraphName = "UseTool Example: Time Expansion"; sc.GraphRegion = 0; sc.AutoLoop = 0; //No automatic looping return; } // Do data processing int BarIndex; int& r_LineNumber = sc.GetPersistentInt(1); s_UseTool Tool; Tool.ChartNumber = sc.ChartNumber; Tool.DrawingType = DRAWING_TIME_EXPANSION; //int &LineNumber17 = sc.GetPersistentInt(17); if (r_LineNumber != 0) Tool.LineNumber = r_LineNumber; BarIndex = max(0, sc.ArraySize - 90); Tool.BeginDateTime = sc.BaseDateTimeIn[BarIndex]; Tool.BeginValue = sc.Close[BarIndex]; BarIndex = max(0, sc.ArraySize - 80); Tool.EndDateTime = sc.BaseDateTimeIn[BarIndex]; Tool.EndValue = sc.Close[BarIndex]; Tool.Color = COLOR_LIGHTPINK; Tool.AddMethod = UTAM_ADD_OR_ADJUST; Tool.RetracementLevels[0] = 100.0f; Tool.RetracementLevels[1] = 200.0f; Tool.RetracementLevels[2] = 300.0f; Tool.RetracementLevels[3] = 400.0f; Tool.RetracementLevels[3] = 800.0f; Tool.RetracementLevels[3] = 1000.0f; Tool.TimeExpTopLabel1 = TIME_EXP_LABEL_PERCENTBARS; Tool.TimeExpBottomLabel1 = TIME_EXP_LABEL_TIME; Tool.TimeExpVerticals = TIME_EXP_COMPRESSED; Tool.TransparentLabelBackground = 1; sc.UseTool(Tool); r_LineNumber = Tool.LineNumber;//Remember line number which has been automatically set } /*==========================================================================*/ SCSFExport scsf_UseToolExampleDrawingMarkerV2(SCStudyInterfaceRef sc) { // Marker example // Set configuration variables if (sc.SetDefaults) { sc.GraphName = "UseTool Example: Marker V2"; sc.GraphRegion = 0; sc.AutoLoop = 0; //No automatic looping return; } // Do data processing int BarIndex; int& r_LineNumber = sc.GetPersistentInt(1); s_UseTool Tool; Tool.ChartNumber = sc.ChartNumber; Tool.DrawingType = DRAWING_MARKER; //int &LineNumber18 = sc.GetPersistentInt(18); if (r_LineNumber != 0) Tool.LineNumber = r_LineNumber; BarIndex = max(0, sc.ArraySize - 35); Tool.BeginDateTime = sc.BaseDateTimeIn[BarIndex]; Tool.BeginValue = sc.High[BarIndex]; Tool.Color = RGB(0, 200, 200); Tool.AddMethod = UTAM_ADD_OR_ADJUST; Tool.MarkerType = MARKER_X; Tool.MarkerSize = 8; Tool.LineWidth = 5; sc.UseTool(Tool); r_LineNumber = Tool.LineNumber;//Remember line number which has been automatically set } /*==========================================================================*/ SCSFExport scsf_UseToolExampleDrawingCalculator(SCStudyInterfaceRef sc) { // Draws a chart calculator line over the last 20 bars. // Set configuration variables if (sc.SetDefaults) { sc.GraphName = "UseTool Example: Calculator"; sc.GraphRegion = 0; sc.AutoLoop = 0; //No automatic looping return; } // Do data processing int BarIndex; int& r_LineNumber = sc.GetPersistentInt(1); s_UseTool Tool; Tool.ChartNumber = sc.ChartNumber; Tool.DrawingType = DRAWING_CALCULATOR; //int &LineNumber19 = sc.GetPersistentInt(19); if (r_LineNumber != 0) Tool.LineNumber = r_LineNumber; // Set BarIndex to 20 bars from the end BarIndex = max(0, sc.ArraySize - 20); //Tool.BeginDateTime = sc.BaseDateTimeIn[BarIndex]; //Tool.EndDateTime = sc.BaseDateTimeIn[sc.ArraySize - 1]; Tool.BeginIndex = BarIndex; Tool.EndIndex = sc.ArraySize - 1; Tool.BeginValue = sc.Low[BarIndex]; Tool.EndValue = sc.High[sc.ArraySize - 1]; Tool.Region = 0; Tool.Color = RGB(255, 255, 255); Tool.LineWidth = 4; Tool.AddMethod = UTAM_ADD_OR_ADJUST; Tool.ShowEndPointPrice = 1; Tool.ShowAngle = 1; Tool.ShowPriceDifference = 1; Tool.ShowNumberOfBars = 1; Tool.ShowTimeDifference = 1; Tool.MultiLineLabel = 1; sc.UseTool(Tool); // Here we make the function call to add the line r_LineNumber = Tool.LineNumber;//Remember line number which has been automatically set } /*==========================================================================*/ SCSFExport scsf_UseToolExampleDrawingCycle(SCStudyInterfaceRef sc) { // Set configuration variables if (sc.SetDefaults) { sc.GraphName = "UseTool Example: Cycle"; sc.GraphRegion = 1; sc.AutoLoop = 0; //No automatic looping return; } int& r_LineNumber = sc.GetPersistentInt(1); if (sc.IsFullRecalculation) { r_LineNumber = 0; } //Add or update cycle drawing. s_UseTool Tool; Tool.Clear(); Tool.ChartNumber = sc.ChartNumber; Tool.Region = 1; if (r_LineNumber != 0) Tool.LineNumber = r_LineNumber; Tool.DrawingType = DRAWING_CYCLE; Tool.BeginDateTime = sc.BaseDateTimeIn[sc.ArraySize - 100]; Tool.EndDateTime = sc.BaseDateTimeIn[sc.ArraySize - 90]; Tool.Color = RGB(255, 255, 0); Tool.LineWidth = 5; Tool.NumCycles = 5; Tool.AddMethod = UTAM_ADD_OR_ADJUST; if (sc.UseTool(Tool) > 0) r_LineNumber = Tool.LineNumber; } /*==========================================================================*/ SCSFExport scsf_UseToolExampleText(SCStudyInterfaceRef sc) { // Use Indexes instead of DateTime Text example. // Set configuration variables if (sc.SetDefaults) { sc.GraphName = "UseTool Example: Text"; sc.GraphRegion = 0; sc.AutoLoop = 0; //No automatic looping return; } // Do data processing int BarIndex; int& r_LineNumber = sc.GetPersistentInt(1); s_UseTool Tool; Tool.ChartNumber = sc.ChartNumber; Tool.DrawingType = DRAWING_TEXT; if (r_LineNumber != 0) Tool.LineNumber = r_LineNumber; // Update BarIndex to 30 bars from the end BarIndex = max(0, sc.ArraySize - 30); //Tool.BeginIndex = BarIndex; Tool.BeginDateTime = 150; Tool.BeginValue = sc.High[BarIndex]; Tool.Color = COLOR_WHITE; Tool.Text.Format("Text On Index: %i", BarIndex); Tool.TextAlignment = DT_RIGHT ; Tool.AddMethod = UTAM_ADD_OR_ADJUST; sc.UseTool(Tool); r_LineNumber = Tool.LineNumber;//Remember line number which has been automatically set } /*==========================================================================*/ SCSFExport scsf_UseToolExampleText75BarsBack(SCStudyInterfaceRef sc) { // User Drawn Drawing example, put 75 bars back // Set configuration variables if (sc.SetDefaults) { sc.GraphName = "UseTool Example: Text 75 Bars Back"; sc.GraphRegion = 0; sc.AutoLoop = 0; //No automatic looping return; } // Do data processing int BarIndex; int& r_TextDrawingLineNumber = sc.GetPersistentInt(1); if (r_TextDrawingLineNumber != 0 && sc.LastCallToFunction) { // Be sure to remove the Text drawing added as a user drawn drawing sc.DeleteUserDrawnACSDrawing(sc.ChartNumber, r_TextDrawingLineNumber); return;//No further processing needed in this case. } int& r_LineNumber = sc.GetPersistentInt(2); s_UseTool Tool; Tool.ChartNumber = sc.ChartNumber; Tool.DrawingType = DRAWING_TEXT; if (r_LineNumber != 0) Tool.LineNumber = r_LineNumber; // Must set user drawn flag Tool.AddAsUserDrawnDrawing = 1; BarIndex = max(0, sc.ArraySize - 75); Tool.BeginIndex = BarIndex; Tool.BeginValue = sc.High[BarIndex]; Tool.Color = COLOR_KHAKI; Tool.Text = "User Drawn Text Example, Move Me"; Tool.FontSize = 18; // do not keep adjusting Tool.AddMethod = UTAM_ADD_ONLY_IF_NEW; sc.UseTool(Tool); //Remember the line number which has been automatically assigned r_LineNumber = Tool.LineNumber; // If the user drawn line exists, we will add a message to the Message Log if (sc.UserDrawnChartDrawingExists(sc.ChartNumber, r_TextDrawingLineNumber)) { sc.AddMessageToLog("User drawn Text exists.", 0); } if (sc.ChartDrawingExists(sc.ChartNumber, r_TextDrawingLineNumber)) { sc.AddMessageToLog("Error: User drawn Text should not exist when calling the ChartDrawingExists().", 1); } } /*==========================================================================*/ SCSFExport scsf_UseToolExampleDrawingFanFibonacci(SCStudyInterfaceRef sc) { // Fibonacci Fan example // Set configuration variables if (sc.SetDefaults) { sc.GraphName = "UseTool Example: Fibonacci Fan"; sc.GraphRegion = 0; sc.AutoLoop = 0; //No automatic looping return; } // Do data processing int BarIndex; int& r_LineNumber = sc.GetPersistentInt(1); s_UseTool Tool; Tool.ChartNumber = sc.ChartNumber; Tool.DrawingType = DRAWING_FAN_FIBONACCI; //int &LineNumber21 = sc.GetPersistentInt(21); if (r_LineNumber != 0) Tool.LineNumber = r_LineNumber; // Update BarIndex to 75 bars from the end BarIndex = sc.ArraySize - 75; BarIndex = max(BarIndex, 0); Tool.BeginDateTime = sc.BaseDateTimeIn[BarIndex]; Tool.BeginValue = sc.High[BarIndex]; BarIndex = sc.ArraySize - 70; BarIndex = max(BarIndex, 0); Tool.EndDateTime = sc.BaseDateTimeIn[BarIndex]; Tool.EndValue = sc.Low[BarIndex]; Tool.ShowLabels = 1; Tool.ShowLabelsAtEnd = 1; //Tool.AllLevelsSameColorStyle = 1; Tool.Color = COLOR_RED; Tool.AddMethod = UTAM_ADD_OR_ADJUST; Tool.RetracementLevels[0] = 50.0f; Tool.LevelColor[0] = COLOR_GREEN; Tool.RetracementLevels[1] = 61.8f; Tool.LevelColor[1] = COLOR_LIGHTGREEN; Tool.RetracementLevels[2] = 100.0f; Tool.LevelColor[2] = COLOR_LIGHTBLUE; Tool.RetracementLevels[3] = 127.2f; Tool.LevelColor[3] = COLOR_LIGHTSTEELBLUE; Tool.RetracementLevels[4] = 161.8f; Tool.LevelColor[4] = COLOR_DARKCYAN; Tool.RetracementLevels[5] = 200.0f; Tool.LevelColor[5] = COLOR_GOLD; sc.UseTool(Tool); r_LineNumber = Tool.LineNumber;//Remember line number which has been automatically set } /*==========================================================================*/ SCSFExport scsf_UseToolExampleDrawingHorizontalLine(SCStudyInterfaceRef sc) { // Set configuration variables if (sc.SetDefaults) { sc.GraphName = "UseTool Example: Horizontal Line"; sc.GraphRegion = 0; sc.AutoLoop = 0; //No automatic looping return; } // Do data processing int BarIndex; int& r_LineNumber = sc.GetPersistentInt(1); s_UseTool Tool; Tool.ChartNumber = sc.ChartNumber; Tool.DrawingType = DRAWING_HORIZONTALLINE; //int &LineNumber22 = sc.GetPersistentInt(22); if (r_LineNumber != 0) Tool.LineNumber = r_LineNumber; // Set BarIndex to 20 bars from the end BarIndex = sc.ArraySize - 20; BarIndex = max(BarIndex, 0); Tool.BeginValue = sc.Close[BarIndex]; Tool.Color = RGB(255, 0, 0); Tool.LineWidth = 10; Tool.Region = 0; Tool.UseToolConfigNum = 1; // must be 1-8 Tool.AddMethod = UTAM_ADD_OR_ADJUST; sc.UseTool(Tool); // Here we make the function call to add the line r_LineNumber = Tool.LineNumber;//Remember line number which has been automatically set } /*==========================================================================*/ SCSFExport scsf_UseToolExampleDrawingHorizontalLineV2(SCStudyInterfaceRef sc) { // Set configuration variables if (sc.SetDefaults) { sc.GraphName = "UseTool Example: Horizontal Line"; sc.GraphRegion = 0; sc.AutoLoop = 0; //No automatic looping return; } int& r_LineNumber = sc.GetPersistentInt(1); if (sc.IsFullRecalculation) { if (r_LineNumber != 0) { sc.DeleteUserDrawnACSDrawing(sc.ChartNumber, r_LineNumber); r_LineNumber = 0; } //Draw horizontal line during full recalculation. s_UseTool Tool; Tool.ChartNumber = sc.ChartNumber; //if (r_LineNumber != 0) //Tool.r_LineNumber = r_LineNumber; Tool.DrawingType = DRAWING_HORIZONTALLINE; Tool.DisplayHorizontalLineValue = 1; int DrawingIndex = sc.ArraySize - 4; Tool.BeginValue = sc.Close[sc.ArraySize - 1]; Tool.Region = 0; Tool.Color = RGB(255, 0, 255); // Magenta Tool.LineWidth = 4; Tool.AddMethod = UTAM_ADD_ALWAYS; Tool.AddAsUserDrawnDrawing = 1; sc.UseTool(Tool); r_LineNumber = Tool.LineNumber; } else if (sc.UpdateStartIndex < sc.ArraySize - 1)//When there is a new bar { //Now move the drawing to the current closing price when a new bar has been added to the chart s_UseTool Tool; ///No need for this //sc.GetUserDrawnDrawingByLineNumber(sc.ChartNumber, LineNumber, Tool); Tool.ChartNumber = sc.ChartNumber; Tool.BeginValue = sc.Close[sc.ArraySize - 1]; Tool.AddMethod = UTAM_ADD_OR_ADJUST; Tool.LineNumber = r_LineNumber; Tool.AddAsUserDrawnDrawing = 1; sc.UseTool(Tool); r_LineNumber = Tool.LineNumber; } } /*==========================================================================*/ SCSFExport scsf_UseToolExampleMultipleDrawingsSameIndex(SCStudyInterfaceRef sc) { // Set configuration variables if (sc.SetDefaults) { sc.GraphName = "UseTool Example: Multiple Drawings At Same Index"; sc.StudyDescription = ""; sc.GraphRegion = 0; sc.AutoLoop = 1; //Automatic looping return; } //Set up persistent line number variables int &LineNumber_1 = sc.GetPersistentInt(1); int &LineNumber_2 = sc.GetPersistentInt(2); if (sc.Index == sc.ArraySize - 1) //only do this at last bar { s_UseTool Tool; Tool.ChartNumber = sc.ChartNumber; if (LineNumber_1 != 0) Tool.LineNumber = LineNumber_1; Tool.DrawingType = DRAWING_MARKER; Tool.BeginIndex = sc.Index; Tool.MarkerType = MARKER_ARROWRIGHT; Tool.BeginValue = sc.Low[sc.Index]; Tool.Region = 0; Tool.Color = RGB(255, 255, 0); Tool.MarkerSize = 8; Tool.LineWidth = 5; Tool.AddMethod = UTAM_ADD_OR_ADJUST; sc.UseTool(Tool); // Here we make the function call to add the marker //Remember the Line Number LineNumber_1 = Tool.LineNumber; //Now add second marker if (LineNumber_2 != 0) Tool.LineNumber = LineNumber_2; else Tool.LineNumber = -1;//automatically assign number Tool.BeginValue = sc.High[sc.Index]; Tool.Color = RGB(128, 255, 0); sc.UseTool(Tool); // Here we make the function call to add the marker LineNumber_2 = Tool.LineNumber; } //int Count = sc.DeleteACSChartDrawing(0, TOOL_DELETE_CHARTDRAWING, LineNumber_2); } /*==========================================================================*/ SCSFExport scsf_UseToolExampleUserDrawnText(SCStudyInterfaceRef sc) { // Set configuration variables if (sc.SetDefaults) { sc.GraphName = "UseTool Example: User Drawn Text"; sc.StudyDescription = "User drawn text drawing example."; sc.GraphRegion = 0; sc.AutoLoop = 0; //No automatic looping return; } int &TextDrawingLineNumber = sc.GetPersistentInt(1); if (sc.LastCallToFunction) { if (TextDrawingLineNumber != 0) { // Be sure to remove the Text drawing added as a user drawn drawing sc.DeleteUserDrawnACSDrawing(sc.ChartNumber, TextDrawingLineNumber); } return; } int BarIndex = sc.ArraySize - 20; if (BarIndex < 0) return; s_UseTool TextDrawing; TextDrawing.Clear();//Not necessary but good practice TextDrawing.ChartNumber = sc.ChartNumber; TextDrawing.DrawingType = DRAWING_TEXT; if(TextDrawingLineNumber != 0) TextDrawing.LineNumber = TextDrawingLineNumber; TextDrawing.AddAsUserDrawnDrawing = 1; TextDrawing.BeginIndex = BarIndex; TextDrawing.BeginValue = sc.High[BarIndex]; TextDrawing.Color = COLOR_KHAKI; TextDrawing.Text = "Movable User Drawn Text Example"; TextDrawing.FontSize = 18; // do not keep adjusting TextDrawing.AddMethod = UTAM_ADD_ONLY_IF_NEW; sc.UseTool(TextDrawing); //Remember the line number which has been automatically assigned TextDrawingLineNumber = TextDrawing.LineNumber; } /*==========================================================================*/ SCSFExport scsf_UseToolExampleStationaryText(SCStudyInterfaceRef sc) { // Set configuration variables if (sc.SetDefaults) { sc.GraphName = "UseTool Example: Stationary Text"; sc.GraphRegion = 0; sc.AutoLoop = 0; //No automatic looping return; } int &TextDrawingLineNumber = sc.GetPersistentInt(1); if (sc.LastCallToFunction) { if (TextDrawingLineNumber != 0) { // Be sure to remove the Text drawing added as a user drawn drawing sc.DeleteUserDrawnACSDrawing(sc.ChartNumber, TextDrawingLineNumber); } return; } s_UseTool TextDrawing; TextDrawing.Clear();//Not necessary but good practice TextDrawing.ChartNumber = sc.ChartNumber; TextDrawing.DrawingType = DRAWING_STATIONARY_TEXT; if (TextDrawingLineNumber != 0) TextDrawing.LineNumber = TextDrawingLineNumber; TextDrawing.AddAsUserDrawnDrawing = 1;// Optional //If this is not set, it will be automatically set to 1 anyway. TextDrawing.UseRelativeVerticalValues = 1; TextDrawing.BeginDateTime = 50; TextDrawing.BeginValue = 50; TextDrawing.Color = COLOR_KHAKI; TextDrawing.Text = "Stationary Text Example"; TextDrawing.FontSize = 18; TextDrawing.AddMethod = UTAM_ADD_OR_ADJUST; sc.UseTool(TextDrawing); //Remember the line number which has been automatically assigned TextDrawingLineNumber = TextDrawing.LineNumber; } /*==========================================================================*/ SCSFExport scsf_UseToolExampleMultilineText(SCStudyInterfaceRef sc) { // Set configuration variables if (sc.SetDefaults) { sc.GraphName = "UseTool Example: Multiline Text"; sc.StudyDescription = ""; sc.GraphRegion = 0; sc.AutoLoop = 0; //No automatic looping return; } // Do data processing int BarIndex = sc.ArraySize - 20; if (BarIndex < 0) return; s_UseTool Tool; Tool.ChartNumber = sc.ChartNumber; int &LineNumber = sc.GetPersistentInt(1); if(LineNumber != 0) Tool.LineNumber = LineNumber; Tool.Region = 0; Tool.DrawingType = DRAWING_TEXT; Tool.AddMethod = UTAM_ADD_OR_ADJUST; // for multi-line text use "\n" as the delimiter and turn on the multi line label flag Tool.Text = "Text Example\nSecond Line\nThird Line\nForth Line"; Tool.MultiLineLabel = 1; Tool.BeginIndex = BarIndex; Tool.BeginValue = sc.Close[BarIndex]; Tool.Color = COLOR_YELLOW; Tool.FontFace = sc.GetChartTextFontFaceName(); // override chart drawing text font Tool.FontSize = 14; Tool.FontBold = 1; sc.UseTool(Tool); LineNumber = Tool.LineNumber;//Remember line number which has been automatically set } /*==========================================================================*/ SCSFExport scsf_UseToolExampleRewardRisk(SCStudyInterfaceRef sc) { // Set configuration variables if (sc.SetDefaults) { sc.GraphName = "UseTool Example: Reward/Risk"; sc.StudyDescription = ""; sc.GraphRegion = 0; sc.AutoLoop = 0; //No automatically looping return; } // Do data processing int BarIndex = sc.ArraySize - 1; if (BarIndex < 20) return; float Entry = sc.Close[BarIndex-1]; float Stop = Entry - 10 * sc.TickSize; float Target = Entry + 20 * sc.TickSize; s_UseTool Tool; Tool.ChartNumber = sc.ChartNumber; int &LineNumber = sc.GetPersistentInt(1); if(LineNumber != 0) Tool.LineNumber = LineNumber; Tool.Region = 0; Tool.AddMethod = UTAM_ADD_OR_ADJUST; Tool.DrawingType = DRAWING_REWARD_RISK; Tool.BeginIndex = BarIndex - 2; Tool.BeginValue = Stop; Tool.EndIndex = BarIndex - 1; Tool.EndValue = Entry; Tool.ThirdIndex = BarIndex; Tool.ThirdValue = Target; Tool.Color = COLOR_YELLOW; // text color Tool.TransparentLabelBackground = 0; // opaque labels Tool.TextAlignment = DT_RIGHT; // text alignment (target marker is left/right of text) Tool.ShowTickDifference = 1; // text options Tool.ShowPriceDifference = 1; Tool.ShowCurrencyValue = 1; Tool.FontFace = sc.GetChartTextFontFaceName(); // override chart drawing text font Tool.FontSize = 14; Tool.FontBold = 1; // remaining options are controlled via the use tool levels Tool.LevelColor[0] = COLOR_DARKRED; // stop to entry line Tool.LevelStyle[0] = LINESTYLE_SOLID; Tool.LevelWidth[0] = 2; Tool.LevelColor[1] = COLOR_DARKGREEN; // entry to target line Tool.LevelStyle[1] = LINESTYLE_SOLID; Tool.LevelWidth[1] = 2; Tool.LevelColor[2] = COLOR_WHITE; // entry marker Tool.LevelStyle[2] = MARKER_POINT; // marker type Tool.RetracementLevels[2] = 8; // marker size Tool.LevelWidth[2] = 3; // marker width Tool.LevelColor[3] = COLOR_RED; // stop marker Tool.LevelStyle[3] = MARKER_DASH; // marker type Tool.RetracementLevels[3] = 8; // marker size Tool.LevelWidth[3] = 3; // marker width Tool.LevelColor[4] = COLOR_ORANGE; // target marker Tool.LevelStyle[4] = MARKER_STAR; // marker type Tool.RetracementLevels[4] = 8; // marker size Tool.LevelWidth[4] = 3; // marker width sc.UseTool(Tool); // here we make the function call to add the reward risk tool LineNumber = Tool.LineNumber; // remember line number which has been automatically set } /*==========================================================================*/ SCSFExport scsf_UseToolVerticalLineText(SCStudyInterfaceRef sc) { // Set configuration variables if (sc.SetDefaults) { sc.GraphName = "UseTool Example: Vertical Line / Text"; sc.StudyDescription = ""; sc.GraphRegion = 0; sc.AutoLoop = 0; //No automatic looping return; } // Do data processing for (int BarIndex = sc.UpdateStartIndex; BarIndex < sc.ArraySize - 1; BarIndex++) { if (BarIndex < 80) continue; s_UseTool Tool; Tool.ChartNumber = sc.ChartNumber; Tool.DrawingType = DRAWING_VERTICALLINE; Tool.Region = 0; Tool.AddMethod = UTAM_ADD_OR_ADJUST; Tool.Color = COLOR_DARKMAGENTA; Tool.LineWidth = 2; Tool.ShowEndPointTime = 1; Tool.MultiLineLabel = 1; Tool.DrawWithinRegion = 1; Tool.FontSize = 7; Tool.TextColor = COLOR_ORANGE; // now draw 8 lines with the different alignment/orientations Tool.BeginIndex = BarIndex - 80; int &LineNumber1 = sc.GetPersistentInt(1); Tool.LineNumber = LineNumber1 != 0 ? LineNumber1 : -1; // use line number once set, otherwise auto-set Tool.Text = "Vertical Text Top/Left Aligned"; Tool.VerticalText = 1; Tool.TextAlignment = DT_TOP | DT_LEFT; sc.UseTool(Tool); LineNumber1 = Tool.LineNumber;//Remember line number which has been automatically set // line 2 Tool.BeginIndex = BarIndex - 70; int &LineNumber2 = sc.GetPersistentInt(2); Tool.LineNumber = LineNumber2 != 0 ? LineNumber2 : -1; Tool.Text = "Vertical Text Top/Right Aligned"; Tool.VerticalText = 1; Tool.TextAlignment = DT_TOP | DT_RIGHT; sc.UseTool(Tool); LineNumber2 = Tool.LineNumber;//Remember line number which has been automatically set // line 3 Tool.BeginIndex = BarIndex - 60; int &LineNumber3 = sc.GetPersistentInt(3); Tool.LineNumber = LineNumber3 != 0 ? LineNumber3 : -1; Tool.Text = "Vertical Text Bottom/Left Aligned"; Tool.VerticalText = 1; Tool.TextAlignment = DT_BOTTOM | DT_LEFT; sc.UseTool(Tool); LineNumber3 = Tool.LineNumber;//Remember line number which has been automatically set // line 4 Tool.BeginIndex = BarIndex - 50; int &LineNumber4 = sc.GetPersistentInt(4); Tool.LineNumber = LineNumber4 != 0 ? LineNumber4 : -1; Tool.Text = "Vertical Text Bottom/Right Aligned"; Tool.VerticalText = 1; Tool.TextAlignment = DT_BOTTOM | DT_RIGHT; sc.UseTool(Tool); LineNumber4 = Tool.LineNumber;//Remember line number which has been automatically set // line 5 Tool.BeginIndex = BarIndex - 40; int &LineNumber5 = sc.GetPersistentInt(5); Tool.LineNumber = LineNumber5 != 0 ? LineNumber5 : -1; Tool.Text = "Horiz Text Top/Left Aligned"; Tool.VerticalText = 0; Tool.TextAlignment = DT_TOP | DT_LEFT; sc.UseTool(Tool); LineNumber5 = Tool.LineNumber;//Remember line number which has been automatically set // line 6 Tool.BeginIndex = BarIndex - 30; int &LineNumber6 = sc.GetPersistentInt(6); Tool.LineNumber = LineNumber6 != 0 ? LineNumber6 : -1; Tool.Text = "Horiz Text Bottom/Left Aligned"; Tool.VerticalText = 0; Tool.TextAlignment = DT_BOTTOM | DT_LEFT; sc.UseTool(Tool); LineNumber6 = Tool.LineNumber;//Remember line number which has been automatically set // line 7 Tool.BeginIndex = BarIndex - 20; int &LineNumber7 = sc.GetPersistentInt(7); Tool.LineNumber = LineNumber7 != 0 ? LineNumber7 : -1; Tool.Text = "Horiz Text Top/Right Aligned"; Tool.VerticalText = 0; Tool.TextAlignment = DT_TOP | DT_RIGHT; sc.UseTool(Tool); LineNumber7 = Tool.LineNumber;//Remember line number which has been automatically set // line 8 Tool.BeginIndex = BarIndex - 10; int &LineNumber8 = sc.GetPersistentInt(8); Tool.LineNumber = LineNumber8 != 0 ? LineNumber8 : -1; Tool.Text = "Horiz Text Bottom/Right Aligned"; Tool.VerticalText = 0; Tool.TextAlignment = DT_BOTTOM | DT_RIGHT; sc.UseTool(Tool); LineNumber8 = Tool.LineNumber;//Remember line number which has been automatically set } } /*==========================================================================*/ SCSFExport scsf_UseToolExampleGannGrid(SCStudyInterfaceRef sc) { // Set configuration variables if (sc.SetDefaults) { sc.GraphName = "UseTool Example: GannGrid"; sc.StudyDescription = ""; sc.GraphRegion = 0; sc.AutoLoop = 0; //No automatic looping return; } // Do data processing for (int BarIndex = sc.UpdateStartIndex; BarIndex < sc.ArraySize - 1; BarIndex++) { if (BarIndex < 100) continue; s_UseTool Tool; Tool.ChartNumber = sc.ChartNumber; int &LineNumber = sc.GetPersistentInt(1); Tool.LineNumber = LineNumber != 0 ? LineNumber : -1; // use line number once set, otherwise auto-set Tool.Region = 0; Tool.AddMethod = UTAM_ADD_OR_ADJUST; Tool.Color = RGB(255, 255, 0); Tool.LineWidth = 2; Tool.DrawingType = DRAWING_GANNGRID; Tool.BeginDateTime = sc.BaseDateTimeIn[BarIndex-20]; Tool.BeginValue = sc.Low[BarIndex-20]; // second point sets Gann line Tool.EndDateTime = sc.BaseDateTimeIn[BarIndex-10]; Tool.EndValue = sc.High[BarIndex-10]; sc.UseTool(Tool); // Here we make the function call to add the marker LineNumber = Tool.LineNumber;//Remember line number which has been automatically set } } /*==========================================================================*/ SCSFExport scsf_UseToolExampleTriangle(SCStudyInterfaceRef sc) { // Set configuration variables if (sc.SetDefaults) { sc.GraphName = "UseTool Example: Triangle"; sc.StudyDescription = ""; sc.GraphRegion = 0; sc.AutoLoop = 0; //No automatic looping return; } // Do data processing for (int BarIndex = sc.UpdateStartIndex; BarIndex < sc.ArraySize - 1; BarIndex++) { if (BarIndex < 100) continue; s_UseTool Tool; Tool.ChartNumber = sc.ChartNumber; int &LineNumber = sc.GetPersistentInt(1); if (LineNumber != 0) Tool.LineNumber = LineNumber; Tool.Region = 0; Tool.AddMethod = UTAM_ADD_OR_ADJUST; Tool.Color = COLOR_DARKBLUE; Tool.SecondaryColor = COLOR_BLUE; Tool.TransparencyLevel = 70; Tool.LineWidth = 2; Tool.DrawingType = DRAWING_TRIANGLE; Tool.BeginDateTime = sc.BaseDateTimeIn[BarIndex-30]; Tool.BeginValue = sc.Low[BarIndex-30]; Tool.EndDateTime = sc.BaseDateTimeIn[BarIndex-20]; Tool.EndValue = sc.High[BarIndex-20]; Tool.ThirdDateTime = sc.BaseDateTimeIn[BarIndex-10]; Tool.ThirdValue = sc.Close[BarIndex-10]; sc.UseTool(Tool); // Here we make the function call to add the marker LineNumber = Tool.LineNumber;//Remember line number which has been automatically set } } /*==========================================================================*/ SCSFExport scsf_AdjustUserDrawnDrawingExample(SCStudyInterfaceRef sc) { // Set configuration variables if (sc.SetDefaults) { sc.GraphName = "Adjust User Drawn Drawing Example"; sc.GraphRegion = 0; sc.UpdateAlways = 1; // We have expressly set auto-looping to off because we are not filling // in any of the Subgraph[].Data[] arrays. Since auto-looping will // cause this function to be called for every bar in the chart and all // we are doing is using tools to do drawings, it would be inefficient // to use auto-looping. sc.AutoLoop = 0; sc.Input[0].Name = "Line Color"; sc.Input[0].SetColor(RGB (255, 0, 255)); return; } //The following code will get all of the Ray drawings on the chart and make them the 'Line Color ' Input color, change the width to 10, and move the starting point back by one bar. Since this function is continuously called with sc.UpdateAlways, this continuously occurs so you will see the Ray drawings continuously move back. int DrawingIndex = 0; s_UseTool DrawingObject; while( sc.GetUserDrawnChartDrawing(sc.ChartNumber, DRAWING_HORIZONTAL_RAY , DrawingObject, DrawingIndex) ) //DRAWING_RAY { DrawingObject.Color =sc.Input[0].GetColor(); DrawingObject.LineWidth = 10; int BarIndex = sc.GetNearestMatchForSCDateTime(sc.ChartNumber, DrawingObject.BeginDateTime); DrawingObject.BeginDateTime = sc.BaseDateTimeIn[BarIndex -1]; DrawingObject.AddMethod = UTAM_ADD_OR_ADJUST; sc.UseTool(DrawingObject); DrawingIndex++; } } /*==========================================================================*/ SCSFExport scsf_DeleteACSChartDrawingExample(SCStudyInterfaceRef sc) { // Set configuration variables if (sc.SetDefaults) { sc.GraphName = "Delete ACS Chart Drawing Example"; sc.StudyDescription = ""; sc.GraphRegion = 0; sc.AutoLoop = 0; //No automatic looping return; } int& LineNumber = sc.GetPersistentInt(1); //Only do processing on the last bar if (sc.IsFullRecalculation) { //Set the previously remembered line number to 0 because on a full recalculation non-user drawn advanced custom study drawings are automatically deleted LineNumber = 0; return; } if(LineNumber != 0) { int Result = sc.DeleteACSChartDrawing(sc.ChartNumber,TOOL_DELETE_CHARTDRAWING, LineNumber); LineNumber = 0; } s_UseTool Tool; Tool.ChartNumber = sc.ChartNumber; //Tool.LineNumber will be automatically set. No need to set this. Tool.DrawingType = DRAWING_MARKER; Tool.BeginIndex = sc.ArraySize - 1; Tool.MarkerType = MARKER_ARROWUP; Tool.BeginValue = sc.Low[sc.ArraySize - 1]; Tool.Region = 0; Tool.Color = RGB(0, 255, 0); Tool.MarkerSize = 8; Tool.LineWidth = 4; Tool.AddMethod = UTAM_ADD_ALWAYS; sc.UseTool(Tool); // Here we make the function call to add the marker //Remember the line number so it can be deleted at the beginning of the function when set LineNumber = Tool.LineNumber; } /*============================================================================ ----------------------------------------------------------------------------*/ SCSFExport scsf_ButtonAndMenuAndPointerExample(SCStudyInterfaceRef sc) { SCString MessageText; // Set configuration variables if (sc.SetDefaults) { sc.GraphName = "Control Bar Button, Menu and Pointer Interaction Example"; sc.StudyDescription = ""; sc.GraphRegion = 0; // We have expressly set Autolooping to off because we are not filling // in any of the Subgraph[].Data[] arrays. Since Autolooping will // cause this function to be called for every bar in the chart it // would be inefficient to use Autolooping. sc.AutoLoop = 0; // Indicate to receive the pointer events always sc.ReceivePointerEvents = ACS_RECEIVE_POINTER_EVENTS_WHEN_ACS_BUTTON_ENABLED; return; } int& r_MenuID = sc.GetPersistentInt(1); int& r_CheckedMenuID = sc.GetPersistentInt(2); int& r_GreyedMenuID = sc.GetPersistentInt(3); int& r_HideMenuID = sc.GetPersistentInt(4); int& r_CheckedState = sc.GetPersistentInt(5); int& r_SeparatorMenuID = sc.GetPersistentInt(6); if (sc.LastCallToFunction) { // Set default hover text and button text. sc.SetCustomStudyControlBarButtonHoverText(1, ""); sc.SetCustomStudyControlBarButtonText(1, ""); // be sure to remove menu items when study is removed sc.RemoveACSChartShortcutMenuItem(sc.ChartNumber, r_MenuID); sc.RemoveACSChartShortcutMenuItem(sc.ChartNumber, r_SeparatorMenuID); sc.RemoveACSChartShortcutMenuItem(sc.ChartNumber, r_CheckedMenuID); sc.RemoveACSChartShortcutMenuItem(sc.ChartNumber, r_GreyedMenuID); sc.RemoveACSChartShortcutMenuItem(sc.ChartNumber, r_HideMenuID); return; } if (sc.UpdateStartIndex == 0) { // Set the ACS Control Bar button 1 hover text sc.SetCustomStudyControlBarButtonHoverText(1, "This is the custom hover text for ACS Control Bar button 1"); // Set the ACS Control Bar button 1 text sc.SetCustomStudyControlBarButtonText(1, "ACS1"); //sc.PlaceACSChartShortcutMenuItemsAtTopOfMenu = true; // add chart short cut menu item if not already added (persist var initialized to zero, negative previous fail) if (r_MenuID <= 0) { r_MenuID = sc.AddACSChartShortcutMenuItem(sc.ChartNumber, "Menu Item example 1"); // add a menu separator r_SeparatorMenuID = sc.AddACSChartShortcutMenuSeparator(sc.ChartNumber); } r_CheckedState = 1; if (r_CheckedMenuID <= 0) { r_CheckedMenuID = sc.AddACSChartShortcutMenuItem(sc.ChartNumber, "Checked Toggle Menu Item"); sc.SetACSChartShortcutMenuItemChecked(sc.ChartNumber, r_CheckedMenuID, true); } if (r_GreyedMenuID <= 0) r_GreyedMenuID = sc.AddACSChartShortcutMenuItem(sc.ChartNumber, "Greyed When Not Checked"); if (r_HideMenuID <= 0) r_HideMenuID = sc.AddACSChartShortcutMenuItem(sc.ChartNumber, "Hidden When Not Checked"); if (r_MenuID < 0 || r_CheckedMenuID < 0 || r_HideMenuID < 0 || r_GreyedMenuID < 0) { MessageText.Format("Add ACS Chart Shortcut menu item failed"); sc.AddMessageToLog(MessageText, 1); } } // wait for an event if (sc.MenuEventID != 0) { if (sc.PointerEventType == SC_POINTER_BUTTON_DOWN) MessageText.Append("Pointer Down Event, "); else if (sc.PointerEventType == SC_POINTER_BUTTON_UP) MessageText.Append("Pointer Up Event, "); else if (sc.PointerEventType == SC_POINTER_MOVE) MessageText.Append("Pointer Move Event, "); if (sc.MenuEventID >= ACS_BUTTON_1 && sc.MenuEventID <= ACS_BUTTON_150) { MessageText.AppendFormat("Got button event id %i, ", sc.MenuEventID); if (sc.PointerEventType == SC_ACS_BUTTON_ON) { MessageText.Append("ACS Button On Event, "); // reset button 1 to off if (sc.MenuEventID == ACS_BUTTON_1) sc.SetCustomStudyControlBarButtonEnable(ACS_BUTTON_1, 0); } else if (sc.PointerEventType == SC_ACS_BUTTON_OFF) MessageText.Append("ACS Button Off Event, "); } else if (sc.MenuEventID == r_MenuID) { MessageText.AppendFormat("Got menu event id %i, ", sc.MenuEventID); } else if (sc.MenuEventID == r_HideMenuID) { MessageText.AppendFormat("Got hidden menu event id %i, ", sc.MenuEventID); } else if (sc.MenuEventID == r_GreyedMenuID) { MessageText.AppendFormat("Got greyed menu event id %i, ", sc.MenuEventID); } else if (sc.MenuEventID == r_CheckedMenuID) { MessageText.AppendFormat("Got checked menu event id %i, CheckedState=%i, ", sc.MenuEventID, r_CheckedState); // toggle states if (r_CheckedState == 0) { r_CheckedState = 1; sc.SetACSChartShortcutMenuItemChecked(sc.ChartNumber, r_CheckedMenuID, true); sc.SetACSChartShortcutMenuItemEnabled(sc.ChartNumber, r_GreyedMenuID, true); sc.SetACSChartShortcutMenuItemDisplayed(sc.ChartNumber, r_HideMenuID, true); } else { r_CheckedState = 0; sc.SetACSChartShortcutMenuItemChecked(sc.ChartNumber, r_CheckedMenuID, false); sc.SetACSChartShortcutMenuItemEnabled(sc.ChartNumber, r_GreyedMenuID, false); sc.SetACSChartShortcutMenuItemDisplayed(sc.ChartNumber, r_HideMenuID, false); } } MessageText.Append("Y Value="); MessageText += sc.FormatGraphValue(sc.ActiveToolYValue, sc.GetValueFormat()); MessageText.Append(", Bar Index="); MessageText += sc.FormatGraphValue(sc.ActiveToolIndex, 0); sc.AddMessageToLog(MessageText, 0); } } /*============================================================================ ----------------------------------------------------------------------------*/ SCSFExport scsf_ReceiveKeyboardEventsExample(SCStudyInterfaceRef sc) { SCString MessageText; // Set configuration variables if (sc.SetDefaults) { sc.GraphName = "Receive Keyboard Events Example"; sc.StudyDescription = ""; sc.GraphRegion = 0; // We have expressly set Autolooping to off because we are not filling // in any of the Subgraph[].Data[] arrays. Since Autolooping will // cause this function to be called for every bar in the chart it // would be inefficient to use Autolooping. sc.AutoLoop = 0; sc.ReceiveKeyboardKeyEvents = 1; sc.ReceiveCharacterEvents = 1; sc.SupportKeyboardModifierStates = 1; return; } // wait for an event if (sc.KeyboardKeyEventCode != 0) { MessageText.AppendFormat("Received keyboard key event. Windows virtual key code: %i, ", sc.KeyboardKeyEventCode); sc.AddMessageToLog(MessageText, 0); } if(sc.CharacterEventCode != 0) { MessageText.AppendFormat("Received character event. ASCII code: %i, ", sc.CharacterEventCode); sc.AddMessageToLog(MessageText, 0); } if (sc.IsKeyPressed_Alt) { sc.AddMessageToLog("Alt key pressed", 0); } if (sc.IsKeyPressed_Shift) { sc.AddMessageToLog("Shift key pressed", 0); } if (sc.IsKeyPressed_Control) { sc.AddMessageToLog("Control key pressed", 0); } } /*============================================================================ This function gives examples of adding messages to the Message Log, playing alert sounds and adding Alert Messages. ----------------------------------------------------------------------------*/ SCSFExport scsf_LogAndAlertExample(SCStudyInterfaceRef sc) { // Set configuration variables if (sc.SetDefaults) { sc.GraphName = "Log and Alert Example"; sc.StudyDescription = ""; sc.GraphRegion = 0; sc.AutoLoop = 0;//manual looping return; } // Do data processing if (sc.GetBarHasClosedStatus(sc.UpdateStartIndex) == BHCS_BAR_HAS_NOT_CLOSED) return; // Show message to log sc.AddMessageToLog("Popped up Message", 1); sc.AddMessageToLog("Non-Popped up Message", 0); // Alert sounds are configured by selecting "Global Settings >> General Settings" in Sierra Chart sc.PlaySound(1); // Add alert sound 1 to be played sc.PlaySound(50); // Add alert sound 50 to be played // Add an Alert message to SierraChart Alert Log sc.AddAlertLine("Condition is TRUE"); // Adding an alert line using an SCString. The Alert log will also be opened. SCString AlertMessage("Alert Message"); sc.AddAlertLine(AlertMessage,1); // Playing a sound and adding an Alert Line at the same time. sc.PlaySound(2, AlertMessage, 1); // Alert Log will open sc.PlaySound(3, "Alert Message 2", 0); // Alert Log will not open // Can also Play Sound from a text file, for example: sc.PlaySound("C:\\Windows\\beep.wav", 2); sc.AddAlertLineWithDateTime("Alert message with date-time", 0, sc.BaseDateTimeIn[sc.UpdateStartIndex]); } /*============================================================================ ----------------------------------------------------------------------------*/ SCSFExport scsf_SelectScaleIncrementWithButtons(SCStudyInterfaceRef sc) { if (sc.SetDefaults) { // Set the configuration and defaults sc.GraphName = "Select Scale Increment with Buttons"; sc.StudyDescription = "This code serves as an example of how to set the base graph scale increment by using control bar buttons."; sc.GraphRegion = 0; sc.AutoLoop = 0; sc.Input[0].Name = "Scale Increment 1"; sc.Input[0].SetFloat(1.0f); sc.Input[1].Name = "Scale Increment 2"; sc.Input[1].SetFloat(2.0f); sc.Input[2].Name = "Scale Increment 3"; sc.Input[2].SetFloat(4.0f); sc.Input[3].Name = "Scale Increment 4"; sc.Input[3].SetFloat(8.0f); return; } if (sc.IsFullRecalculation) { sc.SetCustomStudyControlBarButtonHoverText(ACS_BUTTON_1, "Change to Scale Increment 1 Input"); sc.SetCustomStudyControlBarButtonText(ACS_BUTTON_1, "Scale1"); sc.SetCustomStudyControlBarButtonHoverText(ACS_BUTTON_2, "Change to Scale Increment 2 Input"); sc.SetCustomStudyControlBarButtonText(ACS_BUTTON_2, "Scale2"); sc.SetCustomStudyControlBarButtonHoverText(ACS_BUTTON_3, "Change to Scale Increment 3 Input"); sc.SetCustomStudyControlBarButtonText(ACS_BUTTON_3, "Scale3"); sc.SetCustomStudyControlBarButtonHoverText(ACS_BUTTON_4, "Change to Scale Increment 4 Input"); sc.SetCustomStudyControlBarButtonText(ACS_BUTTON_4, "Scale4"); } // wait for a button if (sc.MenuEventID >= ACS_BUTTON_1 && sc.MenuEventID <= ACS_BUTTON_4) { // reset button to off sc.SetCustomStudyControlBarButtonEnable(sc.MenuEventID, 0); sc.BaseGraphScaleIncrement = sc.Input[sc.MenuEventID - 1].GetFloat(); sc.BaseGraphHorizontalGridLineIncrement = sc.BaseGraphScaleIncrement; } } /*============================================================================ This study displays the simple, exponential, and adaptive moving averages. ----------------------------------------------------------------------------*/ SCSFExport scsf_MovingAverageExample1(SCStudyInterfaceRef sc) { SCSubgraphRef Subgraph_SimpleMA = sc.Subgraph[0]; SCSubgraphRef Subgraph_ExponentialMA = sc.Subgraph[1]; SCSubgraphRef Subgraph_AdaptiveMA = sc.Subgraph[2]; // Set configuration variables if (sc.SetDefaults) { // Set defaults sc.GraphName = "Moving Average Example 1"; sc.StudyDescription = ""; sc.GraphRegion = 0; Subgraph_SimpleMA.Name = "Simple Moving Average"; Subgraph_SimpleMA.DrawStyle = DRAWSTYLE_LINE; Subgraph_SimpleMA.PrimaryColor = RGB(0,255,0); Subgraph_ExponentialMA.Name = "Exponential Moving Average"; Subgraph_ExponentialMA.DrawStyle = DRAWSTYLE_LINE; Subgraph_ExponentialMA.PrimaryColor = RGB(255,0,255); Subgraph_AdaptiveMA.Name = "Adaptive Moving Average"; Subgraph_AdaptiveMA.DrawStyle = DRAWSTYLE_LINE; Subgraph_AdaptiveMA.PrimaryColor = RGB(255,255,0); sc.AutoLoop = 1; return; } // Do data processing // Simple moving average in the first subgraph sc.SimpleMovAvg(sc.Close, Subgraph_SimpleMA, 10); // Exponential moving average in the second subgraph sc.ExponentialMovAvg(sc.Close, Subgraph_ExponentialMA, 10); // Adaptive moving average in the third subgraph sc.AdaptiveMovAvg(sc.Close, Subgraph_AdaptiveMA, 10, 2.0f, 30.0f); } /*============================================================================ This study displays the linear regression indicator, weighted moving average, and wilders moving average. ----------------------------------------------------------------------------*/ SCSFExport scsf_MovingAverageExample2(SCStudyInterfaceRef sc) { SCSubgraphRef Subgraph_LinearRegressionIndicator = sc.Subgraph[0]; SCSubgraphRef Subgraph_WeightedMA = sc.Subgraph[1]; SCSubgraphRef Subgraph_WildersMA = sc.Subgraph[2]; // Set configuration variables if (sc.SetDefaults) { // Set the configuration and defaults sc.GraphName = "Moving Average Example 2"; sc.StudyDescription = ""; sc.GraphRegion = 0; Subgraph_LinearRegressionIndicator.Name = "Linear Regression Indicator"; Subgraph_LinearRegressionIndicator.DrawStyle = DRAWSTYLE_LINE; Subgraph_LinearRegressionIndicator.PrimaryColor = RGB(0,255,0); Subgraph_WeightedMA.Name = "Weighted Moving Average"; Subgraph_WeightedMA.DrawStyle = DRAWSTYLE_LINE; Subgraph_WeightedMA.PrimaryColor = RGB(255,0,255); Subgraph_WildersMA.Name = "Wilders Moving Average"; Subgraph_WildersMA.DrawStyle = DRAWSTYLE_LINE; Subgraph_WildersMA.PrimaryColor = RGB(255,255,0); sc.AutoLoop = 1; return; } // Do data processing // Linear regression indicator in the first subgraph sc.LinearRegressionIndicator(sc.Close, Subgraph_LinearRegressionIndicator, 10); // Weighted moving average in the second subgraph sc.WeightedMovingAverage(sc.Close, Subgraph_WeightedMA, 10); // Wilders moving average in the third subgraph sc.WildersMovingAverage(sc.Close, Subgraph_WildersMA, 10); } /*============================================================================ This study function gives an example of using the sc.GetChartDrawing function. ----------------------------------------------------------------------------*/ SCSFExport scsf_GetChartDrawingExample(SCStudyInterfaceRef sc) { // Set configuration variables if (sc.SetDefaults) { sc.GraphName = "GetChartDrawing Example"; sc.StudyDescription = "This function demonstrates using the sc.GetUserDrawnChartDrawing function."; sc.GraphRegion = 0; sc.AutoLoop = 0; //sc.UpdateAlways = 1; return; } int& r_MarkerLineNumber = sc.GetPersistentInt(1); if (sc.LastCallToFunction && r_MarkerLineNumber != 0) { // Be sure to remove the drawing added as a user drawn drawing sc.DeleteUserDrawnACSDrawing(sc.ChartNumber, r_MarkerLineNumber); return;//No further processing needed in this case. } // Do data processing int& MarkerIndex = sc.GetPersistentInt(2); if (sc.UpdateStartIndex == 0) { MarkerIndex = -1; } if (MarkerIndex == -1 ) { // place a user drawn marker on the chart s_UseTool Tool; Tool.Clear(); Tool.ChartNumber = sc.ChartNumber; Tool.Region = sc.GraphRegion; if (r_MarkerLineNumber != 0) Tool.LineNumber = r_MarkerLineNumber; // Must be user drawn if we are going to be able to use sc.GetUserDrawnDrawingByLineNumber(). Tool.AddAsUserDrawnDrawing = 1; Tool.DrawingType = DRAWING_MARKER; int BarIndex = max(0, sc.ArraySize - 5); Tool.BeginIndex = BarIndex; Tool.BeginValue = sc.High[BarIndex]; Tool.Color = RGB(0,200,200); Tool.AddMethod = UTAM_ADD_OR_ADJUST; Tool.MarkerType = MARKER_X; Tool.MarkerSize = 8; Tool.LineWidth = 5; sc.UseTool(Tool); r_MarkerLineNumber = Tool.LineNumber; MarkerIndex = BarIndex; } s_UseTool ChartDrawing; if (sc.GetUserDrawnChartDrawing(0, DRAWING_UNKNOWN, ChartDrawing, -1) > 0) { SCString BeginDateTimeString = sc.FormatDateTime(ChartDrawing.BeginDateTime); SCString EndDateTimeString = sc.FormatDateTime(ChartDrawing.EndDateTime); SCString Msg; Msg.Format("Details of last Chart Drawing on chart: BeginDateTime=%s, EndDateTime=%s, BeginValue=%f, EndValue=%f, LineNumber = %i.", BeginDateTimeString.GetChars(), EndDateTimeString.GetChars(), ChartDrawing.BeginValue, ChartDrawing.EndValue, ChartDrawing.LineNumber); sc.AddMessageToLog(Msg, 1); } // Gets the user drawn marker and writes log if it moved if (sc.GetUserDrawnDrawingByLineNumber(0, r_MarkerLineNumber, ChartDrawing)) { if (ChartDrawing.BeginIndex != MarkerIndex) { SCString Msg; Msg.Format("Marker was found on current chart, and it moved to index %i", ChartDrawing.BeginIndex); sc.AddMessageToLog(Msg, 1); MarkerIndex = ChartDrawing.BeginIndex; } } } /*==========================================================================*/ SCSFExport scsf_ChangeSettingsExample(SCStudyInterfaceRef sc) { if (sc.SetDefaults) { sc.GraphName = "Change Settings Example"; sc.StudyDescription = "Changes bar period to five minutes."; return; } // Set the bar period to 5 minutes. This change will occur after this function returns, during the next chart update. sc.SecondsPerBar = 5*SECONDS_PER_MINUTE; // 5*SECONDS_PER_MINUTE is the same as 5*60 or 300 if (sc.LastCallToFunction == 1) sc.SecondsPerBar = 1*SECONDS_PER_MINUTE; // Set back to 1 minute } /*==========================================================================*/ SCSFExport scsf_ChangeBarPeriodTypeExample(SCStudyInterfaceRef sc) { if (sc.SetDefaults) { sc.GraphName = "Change Bar Period Type Example"; sc.StudyDescription = "This study is an example to change between Range and Volume Bars. It continuously changes between these two Bar Period Types, so the chart will continuously reload."; return; } if (sc.LastCallToFunction == 1) { sc.SecondsPerBar = 1*SECONDS_PER_MINUTE; // Set back to 1 minute sc.RangeBarType= IBPT_RANGE_IN_TICKS_STANDARD; sc.RangeBarValue = 0; sc.VolumePerBar = 0; sc.NumberOfTradesPerBar = 0; sc.DeltaVolumePerBar = 0; sc.ReversalTicksPerBar = 0; sc.RenkoTicksPerBar = 0; return; } if (!sc.AreRangeBars()) { sc.RangeBarType= IBPT_RANGE_IN_TICKS_STANDARD; sc.RangeBarValue = 2; sc.VolumePerBar = 0; sc.NumberOfTradesPerBar = 0; sc.DeltaVolumePerBar = 0; sc.ReversalTicksPerBar = 0; sc.RenkoTicksPerBar = 0; } else if (!sc.AreVolumeBars()) { sc.RangeBarType= IBPT_RANGE_IN_TICKS_STANDARD; sc.RangeBarValue = 0; sc.VolumePerBar = 5000; sc.NumberOfTradesPerBar = 0; sc.DeltaVolumePerBar = 0; sc.ReversalTicksPerBar = 0; sc.RenkoTicksPerBar = 0; } } /*============================================================================ This is an example of how to use the GetStudyArraysFromChart function. ----------------------------------------------------------------------------*/ SCSFExport scsf_GetStudyArraysFromChartExample(SCStudyInterfaceRef sc) { SCSubgraphRef Subgraph_Line = sc.Subgraph[0]; if (sc.SetDefaults) { // Set the configuration and defaults sc.GraphName = "GetStudyArraysFromChart Example"; sc.StudyDescription = "This is an example of how to use the GetStudyArraysFromChart function."; Subgraph_Line.Name = "Line"; Subgraph_Line.DrawStyle = DRAWSTYLE_LINE; Subgraph_Line.PrimaryColor = RGB(0,255,0); return; } // Do data processing int ChartNumber = 1; // Get the study arrays from the first study in the specified chart SCGraphData StudyData; sc.GetStudyArraysFromChart(ChartNumber, 1, StudyData); // Get the first subgraph array from the study data if(StudyData.GetArraySize() == 0) return; SCFloatArrayRef StudyArray = StudyData[0]; if(StudyArray.GetArraySize() == 0) return; // Copy the array from back to front into our first subgraph int RefIndex = StudyArray.GetArraySize(); for (int Index = sc.ArraySize - 1; Index >= 0; Index--) { Subgraph_Line[Index] = StudyArray[RefIndex]; --RefIndex; if (RefIndex < 0) break; } } /*============================================================================ This example code calculates a 30 period simple moving average and colors the data based on the slope. ----------------------------------------------------------------------------*/ SCSFExport scsf_SimpMovAvgColored(SCStudyInterfaceRef sc) { SCSubgraphRef Subgraph_Average = sc.Subgraph[0]; SCInputRef Input_Length = sc.Input[0]; if (sc.SetDefaults) { // Set the configuration and defaults sc.GraphName = "Simple Moving Average (Colored)"; sc.StudyDescription = ""; Subgraph_Average.Name = "Average"; Subgraph_Average.DrawStyle = DRAWSTYLE_LINE; Subgraph_Average.PrimaryColor = RGB(0,255,0); Subgraph_Average.SecondaryColorUsed = 1; // true Subgraph_Average.SecondaryColor = RGB(0,127,0); Input_Length.Name = "Length"; Input_Length.SetInt(30); Input_Length.SetIntLimits(1,MAX_STUDY_LENGTH); sc.AutoLoop = 1; sc.GraphRegion = 0; return; } // Do data processing // Set the index of the first array element to begin drawing at sc.DataStartIndex = Input_Length.GetInt() - 1; // Calculate a simple moving average for the input array sc.SimpleMovAvg(sc.Close,Subgraph_Average,Input_Length.GetInt()); // Color the data according to the slope if (Subgraph_Average[sc.Index] > Subgraph_Average[sc.Index-1]) { // Rising // Use the primary color Subgraph_Average.DataColor[sc.Index] = Subgraph_Average.PrimaryColor; } else { // Falling // Use the secondary color Subgraph_Average.DataColor[sc.Index] = Subgraph_Average.SecondaryColor; } } /*============================================================================ This is an example of how to use colors, secondary colors, and coloring individual bars in a price graph. ----------------------------------------------------------------------------*/ SCSFExport scsf_ColoredPriceGraph(SCStudyInterfaceRef sc) { SCSubgraphRef Subgraph_Open = sc.Subgraph[0]; SCSubgraphRef Subgraph_High = sc.Subgraph[1]; SCSubgraphRef Subgraph_Low = sc.Subgraph[2]; SCSubgraphRef Subgraph_Close = sc.Subgraph[3]; if (sc.SetDefaults) { // Set the configuration and defaults sc.GraphName = "Colored Price Graph"; sc.StudyDescription = "This is an example of how to use colors, secondary colors, and coloring individual bars in a price graph."; sc.GraphDrawType = GDT_OHLCBAR; // Name the subgraphs // Flag each of the four subgraphs as being able to use secondary colors. Subgraph_Open.Name = "Open"; Subgraph_Open.DrawStyle = DRAWSTYLE_LINE; Subgraph_Open.PrimaryColor = RGB(0,255,0); Subgraph_Open.SecondaryColorUsed = 1; Subgraph_Open.DrawZeros = false; Subgraph_Open.SecondaryColor = RGB(0,127,0); Subgraph_High.Name = "High"; Subgraph_High.DrawStyle = DRAWSTYLE_LINE; Subgraph_High.PrimaryColor = RGB(255,0,255); Subgraph_High.SecondaryColorUsed = 1; Subgraph_High.DrawZeros = false; Subgraph_High.SecondaryColor = RGB(127,0,127); Subgraph_Low.Name = "Low"; Subgraph_Low.DrawStyle = DRAWSTYLE_LINE; Subgraph_Low.PrimaryColor = RGB(255,255,0); Subgraph_Low.SecondaryColorUsed = 1; Subgraph_Low.DrawZeros = false; Subgraph_Low.SecondaryColor = RGB(127,127,0); Subgraph_Close.Name = "Close"; Subgraph_Close.DrawStyle = DRAWSTYLE_LINE; Subgraph_Close.PrimaryColor = RGB(255,127,0); Subgraph_Close.SecondaryColorUsed = 1; Subgraph_Close.DrawZeros = false; Subgraph_Close.SecondaryColor = RGB(127,63,0); sc.AutoLoop = 1; return; } // Do data processing // Loop through the four subgraphs for (int SGIndex = 0; SGIndex < 4; ++SGIndex) { // Copy the data float Value = sc.BaseDataIn[SGIndex][sc.Index]; sc.Subgraph[SGIndex][sc.Index] = Value; // Color with the primary color if there was an increase, // otherwise use the secondary color. if (sc.BaseDataIn[SGIndex][sc.Index] > sc.BaseDataIn[SGIndex][sc.Index - 1]) sc.Subgraph[SGIndex].DataColor[sc.Index] = sc.Subgraph[SGIndex].PrimaryColor; else sc.Subgraph[SGIndex].DataColor[sc.Index] = sc.Subgraph[SGIndex].SecondaryColor; } } /*============================================================================ This function is an example of creating blank space on the right side of the chart that is preserved during updating. ----------------------------------------------------------------------------*/ SCSFExport scsf_FillSpaceExample(SCStudyInterfaceRef sc) { SCInputRef Input_FillSpace = sc.Input[10]; if (sc.SetDefaults) { // Set the configuration and defaults sc.GraphName = "Fill Space Example"; sc.StudyDescription = "This function is an example of creating blank space on the right side of the chart that is preserved during updating."; Input_FillSpace.Name = "FillSpace"; Input_FillSpace.SetYesNo(0); // No return; } // Do data processing if (Input_FillSpace.GetYesNo()) { sc.PreserveFillSpace = 1; // true if (sc.NumFillSpaceBars < 2) sc.NumFillSpaceBars = 10; } } /*============================================================================ This function is an example of using the storage block. ----------------------------------------------------------------------------*/ SCSFExport scsf_StorageBlockExample(SCStudyInterfaceRef sc) { if (sc.SetDefaults) { // Set the configuration and defaults sc.GraphName = "Storage Block Example"; sc.StudyDescription = "This function is an example of using the storage block."; return; } // Do data processing // This is the structure of our data that is to be stored in the storage block struct s_PermData { int Number; char Text[32]; }; // Here we make a pointer to the storage block as if it was a ponter to our structure s_PermData* PermData; PermData = (s_PermData*)sc.StorageBlock; // Here we set data using the members of our structure // This uses the memory of the storage block PermData->Number = 10; strcpy(PermData->Text, "Sample Text"); } /*============================================================================ This function gives an example of making a subgraph name change dynamically. ----------------------------------------------------------------------------*/ SCSFExport scsf_DynamicNameExample(SCStudyInterfaceRef sc) { SCSubgraphRef Subgraph_Value = sc.Subgraph[0]; SCInputRef Input_Value = sc.Input[0]; // Set configuration variables if (sc.SetDefaults) { // Set the configuration and defaults sc.GraphName = "Dymamic Name Example"; sc.StudyDescription = "This function demonstrates how to set a dymamic subgraph name."; // Set the initial subgraph name so that it shows up in the // Subgraph Settings without having to apply the study. Subgraph_Value.Name = "Subgraph"; Subgraph_Value.DrawStyle = DRAWSTYLE_LINE; Subgraph_Value.PrimaryColor = RGB(0,255,0); Input_Value.Name = "Value"; Input_Value.SetFloat(1.5f); return; } // Set the subgraph name to include the value of the input. // This must be outside the above if (sc.SetDefaults) code block so that // it gets executed every time. static SCString SubgraphName; // This must be static so that it does't fall out of scope SubgraphName.Format("Value %f Subgraph", Input_Value.GetFloat()); Subgraph_Value.Name = SubgraphName; // Do data processing } /*============================================================================ This shows how to do a vertical line using the draw style set to Bar. ----------------------------------------------------------------------------*/ SCSFExport scsf_VerticalLine(SCStudyInterfaceRef sc) { SCSubgraphRef Subgraph_VerticalLines = sc.Subgraph[0]; // Set the configuration variables // Force these settings -- the user will not be able to change them sc.ScaleRangeType = SCALE_USERDEFINED; sc.ScaleRangeTop = 2.0f; sc.ScaleRangeBottom = 1.0f; sc.Subgraph[0].DrawStyle = DRAWSTYLE_BAR; if (sc.SetDefaults) { // Set the configuration and defaults sc.GraphName = "Vertical Line"; sc.StudyDescription = "Makes a single vertial line at 7 bars back."; sc.GraphRegion = 0; Subgraph_VerticalLines.Name = "Vertical Lines"; Subgraph_VerticalLines.DrawStyle = DRAWSTYLE_LINE; Subgraph_VerticalLines.PrimaryColor = RGB(255,255,0); // Yellow Subgraph_VerticalLines.DrawZeros = false; return; } // Do data processing // Get the index that the vertical line should be placed at int BarIndex = sc.ArraySize - 7; // 7 bars back // Figure out the number of bars that have been added with this update int BarsAdded = sc.ArraySize - sc.UpdateStartIndex - 1; // Clear the old vertical line in case this is an update if (BarIndex - BarsAdded >= 0) Subgraph_VerticalLines[BarIndex - BarsAdded] = 0.0f; // Add the vertical line if (BarIndex >= 0) Subgraph_VerticalLines[BarIndex] = 3.0f; } /*============================================================================ This shows how to highlight a bar using the Draw Style set to Fill Top and Fill Bottom. ----------------------------------------------------------------------------*/ SCSFExport scsf_BarHighlight(SCStudyInterfaceRef sc) { SCSubgraphRef Subgraph_FillTop = sc.Subgraph[0]; SCSubgraphRef Subgraph_FillBottom = sc.Subgraph[1]; // Set the configuration variables // Force these settings -- the user will not be able to change them sc.ScaleRangeType = SCALE_USERDEFINED; sc.ScaleRangeTop = 2.0f; sc.ScaleRangeBottom = 1.0f; sc.Subgraph[0].DrawStyle = DRAWSTYLE_FILL_RECTANGLE_TOP; sc.Subgraph[1].DrawStyle = DRAWSTYLE_FILL_RECTANGLE_BOTTOM; if (sc.SetDefaults) { // Set the configuration and defaults sc.GraphName = "Bar Highlight"; sc.StudyDescription = "Highlights a single bar at 10 bars back."; sc.GraphRegion = 0; Subgraph_FillTop.Name = "Fill Top"; Subgraph_FillTop.DrawStyle = DRAWSTYLE_LINE; Subgraph_FillTop.PrimaryColor = RGB(127,0,0); // Dark red Subgraph_FillTop.DrawZeros = false; Subgraph_FillBottom.Name = "Fill Bottom"; Subgraph_FillBottom.DrawStyle = DRAWSTYLE_LINE; Subgraph_FillBottom.PrimaryColor = RGB(127,0,0); // Dark red -- it's not really necessary to set this since the color from Fill Top is always used Subgraph_FillBottom.DrawZeros = false; return; } // Do data processing // Get the index that the vertical line should be placed at int BarIndex = sc.ArraySize - 10; // 10 bars back // Figure out the number of bars that have been added with this update int BarsAdded = sc.ArraySize - sc.UpdateStartIndex - 1; // Clear the old vertical line in case this is an update if (BarIndex - BarsAdded >= 0) { Subgraph_FillTop[BarIndex- BarsAdded] = 0.0f; Subgraph_FillBottom[BarIndex- BarsAdded] = 0.0f; } // Add the vertical line if (BarIndex >= 0) { Subgraph_FillTop[BarIndex] = 2.0f; // Top Subgraph_FillBottom[BarIndex] = 1.0f; // Bottom } } /*============================================================================ This shows some examples of how to use Persistent variables. ----------------------------------------------------------------------------*/ SCSFExport scsf_PersistentVariablesExample(SCStudyInterfaceRef sc) { // Set the configuration variables if (sc.SetDefaults) { // Set the configuration and defaults sc.GraphName = "Persistent Variables Example"; sc.AutoLoop = 0; //This is set to true to cause the persistent variables to continuously change as a test for when other charts are referencing them and verifying those other charts are getting updated automatically. sc.UpdateAlways = 1; return; } // You can use references to give the user variables more descriptive // names that you can use below. int& r_PersistentInteger = sc.GetPersistentInt(1); float& r_PersistentFloat = sc.GetPersistentFloat(1); if (sc.UpdateStartIndex == 0) { // When there is a full recalculation of the study, // reset the persistent variables we are using r_PersistentInteger = 0; r_PersistentFloat = 0.0f; } r_PersistentInteger += 12; r_PersistentFloat += 25.5f; // Can also use the set function instead of r_PersistentFloat. sc.SetPersistentFloat(2, 2.5f); } /*============================================================================ Standard Error study ----------------------------------------------------------------------------*/ SCSFExport scsf_StdError(SCStudyInterfaceRef sc) { SCSubgraphRef Subgraph_StdErr = sc.Subgraph[0]; SCInputRef Input_Length = sc.Input[0]; if (sc.SetDefaults) { // Set the configuration and defaults sc.GraphName = "Standard Error"; sc.StudyDescription = ""; // Set the region to draw the graph in. Region zero is the main price graph region. sc.GraphRegion = 1; Subgraph_StdErr.Name = "Std Err"; // Set the color and style of the graph line. If these are not set the default will be used. Subgraph_StdErr.PrimaryColor = RGB(255,0,0); // Red Subgraph_StdErr.DrawStyle = DRAWSTYLE_LINE; Input_Length.Name = "Length"; Input_Length.SetInt(30); Input_Length.SetIntLimits(1,MAX_STUDY_LENGTH); sc.AutoLoop = 1; // Must return before doing any data processing if sc.SetDefaults is set return; } // Do data processing // Use the closing price as the input and the first subgraph for the output sc.StdError(sc.Close, Subgraph_StdErr.Data, Input_Length.GetInt()); } /*==========================================================================*/ SCSFExport scsf_T3(SCStudyInterfaceRef sc) { SCSubgraphRef Subgraph_T3 = sc.Subgraph[0]; SCInputRef Input_InputData = sc.Input[0]; SCInputRef Input_Length = sc.Input[1]; SCInputRef Input_Multiplier = sc.Input[2]; if (sc.SetDefaults) { // Set the configuration and defaults sc.GraphName = "T3"; sc.GraphRegion = 0; sc.StudyDescription = "T3 indicator with adjustable multiplier."; // Settings for the first subgraph Subgraph_T3.Name = "T3"; Subgraph_T3.DrawStyle = DRAWSTYLE_LINE; Subgraph_T3.PrimaryColor = RGB(0,255,0); Subgraph_T3.DrawZeros = false; Input_InputData.Name = "Input Data"; Input_InputData.SetInputDataIndex(SC_LAST); Input_Length.Name = "Length"; Input_Length.SetInt(50); Input_Length.SetIntLimits(1,MAX_STUDY_LENGTH); Input_Multiplier.Name = "Multiplier"; Input_Multiplier.SetFloat(0.84f); sc.AutoLoop = 1; return; } if (sc.Index == 0) { for (int SubgraphIndex = 1; SubgraphIndex <= 6; SubgraphIndex++) { sc.Subgraph[SubgraphIndex].Name.Format("%d", SubgraphIndex); sc.Subgraph[SubgraphIndex].DrawStyle = DRAWSTYLE_IGNORE; sc.Subgraph[SubgraphIndex].DisplayNameValueInWindowsFlags = 0; } } // Do data processing sc.DataStartIndex = Input_Length.GetInt() - 1; // The T3 is calculated with a series of exponential moving averages. We // use the internal extra arrays of sc.Subgraph 0 to hold the intermediate data // that will be used to calculate the final result. sc.T3MovingAverage(sc.BaseDataIn[Input_InputData.GetInputDataIndex()], Subgraph_T3, Input_Multiplier.GetFloat(), Input_Length.GetInt()); sc.Subgraph[1][sc.Index] = Subgraph_T3.Arrays[0][sc.Index]; sc.Subgraph[2][sc.Index] = Subgraph_T3.Arrays[1][sc.Index]; sc.Subgraph[3][sc.Index] = Subgraph_T3.Arrays[2][sc.Index]; sc.Subgraph[4][sc.Index] = Subgraph_T3.Arrays[3][sc.Index]; sc.Subgraph[5][sc.Index] = Subgraph_T3.Arrays[4][sc.Index]; sc.Subgraph[6][sc.Index] = Subgraph_T3.Arrays[5][sc.Index]; } /*============================================================================ This function simply shows some examples of working with date and time values. ----------------------------------------------------------------------------*/ SCSFExport scsf_DateAndTimeExample(SCStudyInterfaceRef sc) { if (sc.SetDefaults) { // Set the configuration and defaults sc.GraphName = "Date and Time Example"; sc.StudyDescription = "Example code for date and time related processing."; return; } // Do data processing // Make sure there's at least one bar if (sc.ArraySize < 1) return; SCString MessageString; // Get the index of the last bar int LastIndex = sc.ArraySize - 1; // Get the last date and time SCDateTime LastDateTime = sc.BaseDateTimeIn[LastIndex]; int LastDate = LastDateTime.GetDate(); int LastTime = LastDateTime.GetTimeInSeconds(); // Write to the message log MessageString.Format("LastDate: %d (days since 1899-12-30), LastTime: %d (seconds since 0:00)", LastDate, LastTime); sc.AddMessageToLog(MessageString, 1); // Get the date and time using the DateAt and TimeAt functions on the date-time array int Date = sc.BaseDateTimeIn.DateAt(LastIndex); int Time = sc.BaseDateTimeIn.TimeAt(LastIndex); // Write to the message log MessageString.Format("Date: %d, Time: %d", Date, Time); sc.AddMessageToLog(MessageString, 1); // Get the hour, minute, second for the time int Hour, Minute, Second; TIME_TO_HMS(Time, Hour, Minute, Second); // Write to the message log MessageString.Format("Hour: %d, Minute: %d, Second: %d", Hour, Minute, Second); sc.AddMessageToLog(MessageString, 1); // Get the day of the week for the date int DayOfWeek = DAY_OF_WEEK(Date); // Write to the message log MessageString.Format("Day of Week: %d (0 = Sunday, 1 = Monday)", DayOfWeek); sc.AddMessageToLog(MessageString, 1); // Construct a time value int Time830 = HMS_TIME(8,30,0); // 8:30:00 AM // Write to the message log MessageString.Format("Time value for 08:30:00: %d", Time830); sc.AddMessageToLog(MessageString, 1); // Construct a DateTime value int Yesterday = LastDate - 1; int Evening = HMS_TIME(17,0,0); // 5:00:00 PM SCDateTime YesterdayEvening = SCDateTime(Yesterday, Evening); // Write to the message log MessageString.Format("DateTime value for yesterday evening: %s", sc.FormatDateTime(YesterdayEvening).GetChars()); sc.AddMessageToLog(MessageString, 1); // Get the date and time back out of the SCDateTime value by using GetDate and GetTime Date = YesterdayEvening.GetDate(); Time = YesterdayEvening.GetTimeInSeconds(); // Write to the message log MessageString.Format("Date: %d, Time: %d", Date, Time); sc.AddMessageToLog(MessageString, 1); // Get the year/month/day of yesterday int Year, Month, Day; YesterdayEvening.GetDateYMD(Year, Month, Day); // Write to the message log MessageString.Format("Yesterday: %d-%02d-%02d", Year, Month, Day); sc.AddMessageToLog(MessageString, 1); // Construct the full date-time for Jan 1, 2000 at noon SCDateTime DateTime(2000, 1, 1, 12, 0, 0); // Write to the message log MessageString.Format("Jan 1, 2000 at noon: %s",sc.FormatDateTime(DateTime).GetChars()); sc.AddMessageToLog(MessageString, 1); // Print the year/month/day/hour/minute/second from the date-time // constructed above. This should print 2000-01-01 12:00:00. DateTime.GetDateTimeYMDHMS(Year, Month, Day, Hour, Minute, Second); // Write to the message log MessageString.Format("Jan 1, 2000 at noon from DateTime: %d-%02d-%02d %02d:%02d:%02d", Year, Month, Day, Hour, Minute, Second); sc.AddMessageToLog(MessageString, 1); // Go back 38 hours and print that date-time DateTime -= 38*HOURS; DateTime.GetDateTimeYMDHMS(Year, Month, Day, Hour, Minute, Second); // Write to the message log MessageString.Format("38 hours back: %d-%02d-%02d %02d:%02d:%02d", Year, Month, Day, Hour, Minute, Second); sc.AddMessageToLog(MessageString, 1); // Convert the DateTime from New York time to the time zone used for charts DateTime = sc.ConvertDateTimeToChartTimeZone(DateTime, TIMEZONE_NEW_YORK); DateTime.GetDateTimeYMDHMS(Year, Month, Day, Hour, Minute, Second); // Write to the message log MessageString.Format("Converted from New York time: %d-%02d-%02d %02d:%02d:%02d", Year, Month, Day, Hour, Minute, Second); sc.AddMessageToLog(MessageString, 1); } /*============================================================================ Graphs the highest and lowest value over the last Length bars. ----------------------------------------------------------------------------*/ SCSFExport scsf_HighestAndLowest(SCStudyInterfaceRef sc) { SCSubgraphRef Subgraph_HighestHigh = sc.Subgraph[0]; SCSubgraphRef Subgraph_LowestLow = sc.Subgraph[1]; SCInputRef Input_HighInputData = sc.Input[0]; SCInputRef Input_LowInputData = sc.Input[1]; SCInputRef Input_Length = sc.Input[2]; if (sc.SetDefaults) { // Set the configuration and defaults sc.GraphName = "Highest High and Lowest Low"; sc.StudyDescription = "This graphs the highest high and lowest low over a specified length."; sc.GraphRegion = 0; Subgraph_HighestHigh.Name = "Highest High"; Subgraph_HighestHigh.DrawStyle = DRAWSTYLE_DASH; Subgraph_HighestHigh.PrimaryColor = RGB(0,255,0); Subgraph_LowestLow.Name = "Lowest Low"; Subgraph_LowestLow.DrawStyle = DRAWSTYLE_DASH; Subgraph_LowestLow.PrimaryColor = RGB(255,0,255); Input_HighInputData.Name = "High Input Data"; Input_HighInputData.SetInputDataIndex(SC_HIGH); Input_LowInputData.Name = "Low Input Data"; Input_LowInputData.SetInputDataIndex(SC_LOW); Input_Length.Name = "Length"; Input_Length.SetInt(30); Input_Length.SetIntLimits(1,MAX_STUDY_LENGTH); sc.AutoLoop = 1; return; } // Do data processing // Fill in the highest high and lowest low sc.Highest(sc.BaseDataIn[Input_HighInputData.GetInputDataIndex()], Subgraph_HighestHigh, Input_Length.GetInt()); sc.Lowest(sc.BaseDataIn[Input_LowInputData.GetInputDataIndex()], Subgraph_LowestLow, Input_Length.GetInt()); } /*============================================================================ Calculates the advance decline line. ----------------------------------------------------------------------------*/ SCSFExport scsf_AdvanceDeclineLine(SCStudyInterfaceRef sc) { SCSubgraphRef Subgraph_ADL = sc.Subgraph[0]; SCInputRef Input_ResetAtSessionStart = sc.Input[1]; if (sc.SetDefaults) { // Set the defaults sc.GraphName = "Advance Decline Line"; sc.StudyDescription = "This calculates the advance decline line from a symbol that indicates advancing issues minus declining issues. It normally is added to a chart with the symbol NISS-NYSE."; sc.AutoLoop = 0; Subgraph_ADL.Name = "ADL"; Subgraph_ADL.DrawStyle = DRAWSTYLE_LINE; Subgraph_ADL.PrimaryColor = RGB(0,255,0); Input_ResetAtSessionStart.Name = "Reset at Start of Trading Day"; Input_ResetAtSessionStart.SetYesNo(0); return; } // Do data processing SCDateTime NextSessionStart = sc.GetTradingDayStartDateTimeOfBar(sc.BaseDateTimeIn[sc.UpdateStartIndex - 1]) + SCDateTime(1, 0); if (sc.UpdateStartIndex == 0) { Subgraph_ADL[0] = sc.Close[0]; } for (int BarIndex = max(sc.UpdateStartIndex, 1); BarIndex < sc.ArraySize; BarIndex++) { Subgraph_ADL[BarIndex] = Subgraph_ADL[BarIndex - 1] + sc.Close[BarIndex]; if (Input_ResetAtSessionStart.GetYesNo() != 0) { SCDateTime IndexDateTime = sc.BaseDateTimeIn[BarIndex]; if (IndexDateTime >= NextSessionStart) { Subgraph_ADL[BarIndex] = sc.Close[BarIndex]; NextSessionStart = sc.GetTradingDayStartDateTimeOfBar(IndexDateTime) + 1 * DAYS; } } } } /************************************************************************/ SCSFExport scsf_AdvanceDeclineLine2Chart(SCStudyInterfaceRef sc) { SCSubgraphRef Subgraph_ADL = sc.Subgraph[0]; if (sc.SetDefaults) { // Set the defaults sc.GraphName = "Advance Decline Line - 2 Chart"; sc.StudyDescription = "This calculates the advance decline line from two symbols that indicate advancing issues and declining issues."; sc.AutoLoop= 1; Subgraph_ADL.Name = "ADL"; Subgraph_ADL.DrawStyle = DRAWSTYLE_LINE; Subgraph_ADL.PrimaryColor = RGB(0,255,0); return; } // Do data processing if (sc.Index <1) return; // sc.GetChartArray() Subgraph_ADL[sc.Index] = Subgraph_ADL[sc.Index - 1] + sc.Close[sc.Index]; } /************************************************************************/ /*============================================================================ This uses two subgraphs designed to control the high and low of the chart's scale so that the last bar fills a certain percentage of the height of the chart. ----------------------------------------------------------------------------*/ SCSFExport scsf_CustomScaling(SCStudyInterfaceRef sc) { SCSubgraphRef Subgraph_Top = sc.Subgraph[0]; SCSubgraphRef Subgraph_Bottom = sc.Subgraph[1]; SCInputRef Input_PercentageInput = sc.Input[0]; SCInputRef Input_DefaultRange = sc.Input[1]; if (sc.SetDefaults) { // Set the configuration and defaults sc.GraphName = "Custom Scale Control"; sc.StudyDescription = "Apply this study to a chart. Go to Chart >> Chart Settings, press Scale, and set the Scale Range to Same As Region. All the studies in chart region 1 also need to be set to Same As Region. The \"Percentage\" input is the percentage of the height of the chart that the last bar will fill from high to low. The \"Default Range\" input is the range that is used when the last bar has no range (i.e. high and low are the same)."; sc.UpdateAlways = 1; // true sc.GraphRegion = 0; sc.AutoLoop = 0; Subgraph_Top.Name = "Top"; Subgraph_Top.DrawStyle = DRAWSTYLE_HIDDEN; Subgraph_Top.PrimaryColor = RGB(0,255,0); Subgraph_Top.DrawZeros = false; Subgraph_Bottom.Name = "Bottom"; Subgraph_Bottom.DrawStyle = DRAWSTYLE_HIDDEN; Subgraph_Bottom.PrimaryColor = RGB(255,0,255); Subgraph_Bottom.DrawZeros = false; Input_PercentageInput.Name = "Percentage"; Input_PercentageInput.SetFloat(30.0f); Input_PercentageInput.SetFloatLimits(1.0f, 100.0f); Input_DefaultRange.Name = "Default Range"; Input_DefaultRange.SetFloat(0.1f); Input_DefaultRange.SetFloatLimits(0.00001f, FLT_MAX); return; } // Do data processing // Persistent variables int& LastScaleBar = sc.GetPersistentInt(1); // Clear old scaling Subgraph_Top[LastScaleBar] = 0.0f; Subgraph_Bottom[LastScaleBar] = 0.0f; // Get the high and low of the last bar float LastBarHigh = sc.High[sc.IndexOfLastVisibleBar]; float LastBarLow = sc.Low[sc.IndexOfLastVisibleBar]; // Figure out the range and center of the last bar float LastBarRange = LastBarHigh - LastBarLow; float LastBarCenter = LastBarLow + LastBarRange / 2; // Make sure we have a range other than zero if (LastBarRange == 0) LastBarRange = Input_DefaultRange.GetFloat(); // Get the actual percentage float Percentage = Input_PercentageInput.GetFloat() * 0.01f; if (Percentage == 0.0f) // Prevent a divide-by-zero, though the input limits should already prevent this Percentage = 0.01f; // Calculate the range for the scale float ScaleRange = LastBarRange / Percentage; float ScaleRangeTop = LastBarCenter + ScaleRange / 2; float ScaleRangeBottom = LastBarCenter - ScaleRange / 2; // Pick a bar in the middle to put the scale top and bottom on int ScaleBarIndex = sc.IndexOfFirstVisibleBar + (sc.IndexOfLastVisibleBar - sc.IndexOfFirstVisibleBar) / 2; Subgraph_Top[ScaleBarIndex] = ScaleRangeTop; Subgraph_Bottom[ScaleBarIndex] = ScaleRangeBottom; // Remember the bar we put the scaling on LastScaleBar = ScaleBarIndex; SCString NumberText; NumberText.Format("%d", sc.Index); sc.AddMessageToLog(NumberText, false); } /*============================================================================ Example function for using sc.GetBarHasClosedStatus(). ----------------------------------------------------------------------------*/ SCSFExport scsf_BarHasClosedExample(SCStudyInterfaceRef sc) { if (sc.SetDefaults) { // Set the configuration and defaults sc.GraphName = "Bar Has Closed"; sc.StudyDescription = "This study is an example of how to use the BarHasClosedStatus member function."; return; } // Do data processing int status = sc.GetBarHasClosedStatus(sc.UpdateStartIndex); if (status == BHCS_BAR_HAS_CLOSED) sc.AddMessageToLog("Bar Has Closed", true); if (status == BHCS_BAR_HAS_NOT_CLOSED) sc.AddMessageToLog("Bar Has Not Closed", true); return; } /*============================================================================ This study function colors bars according to if they are above or below a given study subgraph. ----------------------------------------------------------------------------*/ SCSFExport scsf_ColorBarAboveBelow(SCStudyInterfaceRef sc) { SCSubgraphRef Subgraph_ColorBar = sc.Subgraph[0]; SCInputRef Input_InputData = sc.Input[0]; SCInputRef Input_StudyReference = sc.Input[1]; SCInputRef Input_Mode = sc.Input[3]; SCInputRef Input_OutputType = sc.Input[4]; SCInputRef Input_Displacement = sc.Input[5]; if (sc.SetDefaults) { // Set the configuration and defaults sc.GraphName = "Color Bar Based On Above/Below Study"; sc.StudyDescription = "Colors the main price graph bars depending on if the price is above or below a given study subgraph."; sc.GraphRegion = 0; sc.CalculationPrecedence = LOW_PREC_LEVEL; Subgraph_ColorBar.Name = "Color Bar"; Subgraph_ColorBar.DrawStyle = DRAWSTYLE_COLOR_BAR; Subgraph_ColorBar.SecondaryColorUsed = 1; // true Subgraph_ColorBar.PrimaryColor = RGB(0,255,0); Subgraph_ColorBar.SecondaryColor = RGB(255,0,0); Subgraph_ColorBar.DrawZeros = false; Input_InputData.Name = "Input Data"; Input_InputData.SetInputDataIndex(SC_LAST); Input_StudyReference.Name = "Study Reference"; Input_StudyReference.SetStudySubgraphValues(1,0); Input_Mode.Name = "Mode"; Input_Mode.SetCustomInputStrings("Color Above/Below;Color Below;Color Above"); Input_Mode.SetCustomInputIndex(0); Input_OutputType.Name = "Output Input Data Values Instead of 1.0"; Input_OutputType.SetYesNo(false); Input_Displacement.Name = "Study Reference Displacement"; Input_Displacement.SetInt(0); sc.AutoLoop = 1; return; } // Do data processing // Get the study subgraph SCFloatArray SubgraphArray; sc.GetStudyArrayUsingID(Input_StudyReference.GetStudyID(), Input_StudyReference.GetSubgraphIndex(), SubgraphArray); if (SubgraphArray.GetArraySize() == 0) return; // No subgraph data // Get the values from the main price graph and the study subgraph float BaseValue = sc.BaseDataIn[Input_InputData.GetInputDataIndex()][sc.Index]; float SubgraphValue = SubgraphArray[sc.Index-Input_Displacement.GetInt()]; // Color above values using the primary color, and below values using the secondary color. The values in the ColorBar Subgraph need to be non-zero for the main price graph bars to be colored. float OutputValue = 1; if (Input_OutputType.GetYesNo()) OutputValue = BaseValue; if (BaseValue > SubgraphValue && (Input_Mode.GetInt() == 0 || Input_Mode.GetInt() == 2)) { Subgraph_ColorBar[sc.Index] = OutputValue;// 1; Subgraph_ColorBar.DataColor[sc.Index] = Subgraph_ColorBar.PrimaryColor; } else if (BaseValue < SubgraphValue && (Input_Mode.GetInt() == 0 || Input_Mode.GetInt() == 1)) { Subgraph_ColorBar[sc.Index] = OutputValue;//1; Subgraph_ColorBar.DataColor[sc.Index] = Subgraph_ColorBar.SecondaryColor; } else { Subgraph_ColorBar[sc.Index] = 0; } } /*==========================================================================*/ SCSFExport scsf_VolatilityTrend(SCStudyInterfaceRef sc) { SCSubgraphRef Subgraph_VolatilityTrend = sc.Subgraph[0]; SCSubgraphRef Subgraph_TrueRange = sc.Subgraph[1]; SCSubgraphRef Subgraph_AverageTrueRange = sc.Subgraph[2]; SCSubgraphRef Subgraph_Direction = sc.Subgraph[3]; SCSubgraphRef Subgraph_DynamicPeriodLength = sc.Subgraph[4]; SCInputRef Input_ATRLength = sc.Input[0]; SCInputRef Input_ATRType = sc.Input[1]; SCInputRef Input_ATRMultiplier = sc.Input[2]; SCInputRef Input_MaxDynamicPeriod= sc.Input[3]; SCInputRef Input_DynamicPeriodDataInput = sc.Input[4]; // Configuration if (sc.SetDefaults) { sc.GraphName = "Volatility Trend Indicator"; sc.StudyDescription = "Volatility Trend Indicator"; sc.GraphRegion = 0; // Zero based chart region number Input_ATRLength.Name = "Average True Range Length"; Input_ATRLength.SetInt(21); Input_ATRLength.SetIntLimits(1, MAX_STUDY_LENGTH); Input_ATRType.Name = "ATR Moving Average Type"; Input_ATRType.SetMovAvgType(MOVAVGTYPE_WEIGHTED); Input_ATRMultiplier.Name = "ATR Multiplier"; Input_ATRMultiplier.SetFloat(3); Input_MaxDynamicPeriod.Name = "Max. Dynamic Period for Trend Calculation"; Input_MaxDynamicPeriod.SetInt(50); Input_MaxDynamicPeriod.SetIntLimits(1, MAX_STUDY_LENGTH); Input_DynamicPeriodDataInput.Name = "Dynamic Period Input Data"; Input_DynamicPeriodDataInput.SetInputDataIndex(SC_LAST); Subgraph_VolatilityTrend.Name = "Volatility Trend"; Subgraph_VolatilityTrend.DrawStyle = DRAWSTYLE_LINE; Subgraph_VolatilityTrend.PrimaryColor = RGB(0, 128, 0); // green Subgraph_VolatilityTrend.SecondaryColor = RGB(128, 0, 0); // red Subgraph_VolatilityTrend.SecondaryColorUsed = 1; Subgraph_VolatilityTrend.DrawZeros = false; Subgraph_DynamicPeriodLength.Name = "Dynamic Period Length"; Subgraph_DynamicPeriodLength.DrawStyle = DRAWSTYLE_IGNORE; Subgraph_DynamicPeriodLength.PrimaryColor = RGB(255,0,0); Subgraph_DynamicPeriodLength.DrawZeros = false; sc.AutoLoop = 1; return; } COLORREF UpTrendColor = Subgraph_VolatilityTrend.PrimaryColor; COLORREF DownTrendColor = Subgraph_VolatilityTrend.SecondaryColor; sc.DataStartIndex = Input_ATRLength.GetInt()-1; // Data processing if (sc.Index < 1) return; sc.ATR(sc.BaseDataIn, Subgraph_TrueRange, Subgraph_AverageTrueRange, Input_ATRLength.GetInt(), Input_ATRType.GetMovAvgType()); //trend is considered up when price bar value is greater than the volatility trend of the prior bar. Otherwise considered down. if (sc.BaseDataIn[Input_DynamicPeriodDataInput.GetInputDataIndex()][sc.Index] > Subgraph_VolatilityTrend[sc.Index-1]) Subgraph_Direction[sc.Index] = 1; // uptrend else Subgraph_Direction[sc.Index] = -1; // downtrend int Period = (int)(Subgraph_DynamicPeriodLength[sc.Index-1]+0.5f); if (Subgraph_Direction[sc.Index] != Subgraph_Direction[sc.Index-1]) // Different trend than previous Period = 0; if (Period < Input_MaxDynamicPeriod.GetInt()) Period++; Subgraph_DynamicPeriodLength[sc.Index] = (float)Period; if (Subgraph_Direction[sc.Index] == 1) // uptrend { float PeriodHigh = sc.GetHighest(sc.BaseDataIn[Input_DynamicPeriodDataInput.GetInputDataIndex()], Period); Subgraph_VolatilityTrend[sc.Index] = PeriodHigh - Input_ATRMultiplier.GetFloat() * Subgraph_AverageTrueRange[sc.Index]; Subgraph_VolatilityTrend.DataColor[sc.Index] = UpTrendColor; } else // downtrend { float PeriodLow = sc.GetLowest(sc.BaseDataIn[Input_DynamicPeriodDataInput.GetInputDataIndex()], Period); Subgraph_VolatilityTrend[sc.Index] = PeriodLow + Input_ATRMultiplier.GetFloat() * Subgraph_AverageTrueRange[sc.Index]; Subgraph_VolatilityTrend.DataColor[sc.Index] = DownTrendColor; } } /*==========================================================================*/ SCSFExport scsf_AverageTrueRangeStop(SCStudyInterfaceRef sc) { SCSubgraphRef Subgraph_StopL = sc.Subgraph[0]; SCSubgraphRef Subgraph_StopS = sc.Subgraph[1]; // Configuration if (sc.SetDefaults) { sc.GraphName = "Stop"; sc.GraphRegion = 0; // zero based region number Subgraph_StopL.Name = "Stop L"; Subgraph_StopL.DrawStyle = DRAWSTYLE_STAIR_STEP; Subgraph_StopL.PrimaryColor = RGB(0,185,47); Subgraph_StopS.Name = "Stop S"; Subgraph_StopS.DrawStyle = DRAWSTYLE_STAIR_STEP; Subgraph_StopS.PrimaryColor = RGB(255,0,128); sc.AutoLoop = 1; return; } // Data processing // LongSignal = C > ( LLV( L, 20 ) + 2 * ATR( 10 ) ); // ATR with Wilder's MA // ShortSignal = C < ( HHV( H, 20 ) - 2 * ATR( 10 ) ); // LongStopValue = HHV( C - 2 * ATR(10), 15 ); // ShortStopValue = LLV( C + 2 * ATR(10), 15 ); sc.DataStartIndex = 21; // start drawing subgraph at bar #21 (zero based) // ATR(10, Wilder's MA): subgraph #11. Intermediate TR: subgraph #10 (can't be removed) sc.ATR(sc.BaseDataIn, sc.Subgraph[2], sc.Subgraph[3], 10, MOVAVGTYPE_WILDERS); // LLV(L,20): subgraph #6 sc.Lowest(sc.Low, sc.Subgraph[6], 20); // HHV(H,20): subgraph#7 sc.Highest(sc.High, sc.Subgraph[7], 20); // LLV(L,p) + 2*ATR(p,m): subgraph #8 sc.Subgraph[8][sc.Index] = sc.Subgraph[6][sc.Index] + 2 * sc.Subgraph[3][sc.Index]; // HHV(H,p) - 2*ATR(p,m): subgraph #9 sc.Subgraph[9][sc.Index] = sc.Subgraph[7][sc.Index] - 2 * sc.Subgraph[3][sc.Index]; // Close - 2*ATR(p,m): subgraph #12 sc.Subgraph[12][sc.Index] = sc.Close[sc.Index] - 2 * sc.Subgraph[3][sc.Index]; // Close + 2*ATR(p,m): subgraph #13 sc.Subgraph[13][sc.Index] = sc.Close[sc.Index] + 2 * sc.Subgraph[3][sc.Index]; // Continuous LongStopValue: subgraph #14 sc.Highest(sc.Subgraph[12], sc.Subgraph[14], 15); // Continuous ShortStopValue: subgraph #15 sc.Lowest(sc.Subgraph[13], sc.Subgraph[15], 15); // If LongSignal=true, plot LongStopValue in Subgraph #0, otherwise plot null if (sc.Close[sc.Index] > sc.Subgraph[8][sc.Index]) Subgraph_StopL[sc.Index] = sc.Subgraph[14][sc.Index]; else Subgraph_StopL[sc.Index] = 0; // If ShortSignal=true, plot ShortStopValue in Subgraph #1, otherwise plot null if (sc.Close[sc.Index] < sc.Subgraph[9][sc.Index]) Subgraph_StopS[sc.Index] = sc.Subgraph[15][sc.Index]; else Subgraph_StopS[sc.Index] = 0; } /*==========================================================================*/ SCSFExport scsf_DepthOfMarketData(SCStudyInterfaceRef sc) //scsf_DOMAccess { SCSubgraphRef Subgraph_BidSize = sc.Subgraph[0]; SCSubgraphRef Subgraph_BidValue = sc.Subgraph[1]; SCSubgraphRef Subgraph_AskSize = sc.Subgraph[2]; SCSubgraphRef Subgraph_AskValue = sc.Subgraph[3]; SCSubgraphRef Subgraph_BidStackPullValue = sc.Subgraph[4]; SCSubgraphRef Subgraph_AskStackPullValue = sc.Subgraph[5]; if (sc.SetDefaults) { // Set the configuration and defaults sc.GraphName = "Depth of Market Data"; sc.StudyDescription = "This is a study to display current market depth data. When adding this study, also add the Spreadsheet Study to your chart to view the market depth data in a table form on the spreadsheet."; sc.UsesMarketDepthData = 1; Subgraph_BidSize.Name = "Bid Size"; Subgraph_BidSize.DrawStyle = DRAWSTYLE_DASH; Subgraph_BidSize.PrimaryColor = RGB(0,255,0); Subgraph_BidSize.DrawZeros = false; Subgraph_BidValue.Name = "Bid Value"; Subgraph_BidValue.DrawStyle = DRAWSTYLE_DASH; Subgraph_BidValue.PrimaryColor = RGB(255,0,255); Subgraph_BidValue.DrawZeros = false; Subgraph_AskSize.Name = "Ask Size"; Subgraph_AskSize.DrawStyle = DRAWSTYLE_DASH; Subgraph_AskSize.PrimaryColor = RGB(255,255,0); Subgraph_AskSize.DrawZeros = false; Subgraph_AskValue.Name = "Ask Value"; Subgraph_AskValue.DrawStyle = DRAWSTYLE_DASH; Subgraph_AskValue.PrimaryColor = RGB(255,127,0); Subgraph_AskValue.DrawZeros = false; Subgraph_AskStackPullValue.Name = "Ask Stack/Pull Value"; Subgraph_AskStackPullValue.DrawStyle = DRAWSTYLE_IGNORE; Subgraph_AskStackPullValue.PrimaryColor = RGB(128, 128, 128); Subgraph_AskStackPullValue.DrawZeros = false; Subgraph_BidStackPullValue.Name = "Bid Stack/Pull Value"; Subgraph_BidStackPullValue.DrawStyle = DRAWSTYLE_IGNORE; Subgraph_BidStackPullValue.PrimaryColor = RGB(128, 128, 128); Subgraph_BidStackPullValue.DrawZeros = false; return; } // Do data processing int& PriorIndex = sc.GetPersistentInt(1); const int MaximumMarketDepthLevels = sc.GetMaximumMarketDepthLevels(); if (sc.ArraySize - MaximumMarketDepthLevels < 0) return; int BidArrayLevels = sc.GetBidMarketDepthNumberOfLevels(); for (int Level = 0; Level < BidArrayLevels; Level++) { int OutputIndex = sc.ArraySize - 1 - Level; s_MarketDepthEntry DepthEntry; sc.GetBidMarketDepthEntryAtLevel(DepthEntry, Level); Subgraph_BidSize[OutputIndex] = (float)DepthEntry.Quantity; Subgraph_BidValue[OutputIndex] = DepthEntry.Price; float StackPullValue = (float)sc.GetBidMarketDepthStackPullValueAtPrice(DepthEntry.Price); Subgraph_BidStackPullValue[OutputIndex] = StackPullValue; } int AskArrayLevels = sc.GetAskMarketDepthNumberOfLevels(); for (int Level = 0; Level < AskArrayLevels; Level++) { int OutputIndex = sc.ArraySize - 1 - Level; s_MarketDepthEntry DepthEntry; sc.GetAskMarketDepthEntryAtLevel(DepthEntry, Level); Subgraph_AskSize[OutputIndex] = (float)DepthEntry.Quantity; Subgraph_AskValue[OutputIndex] = DepthEntry.Price; float StackPullValue = (float)sc.GetAskMarketDepthStackPullValueAtPrice(DepthEntry.Price); Subgraph_AskStackPullValue[OutputIndex] = StackPullValue; } int LastIndex = sc.ArraySize - MaximumMarketDepthLevels; sc.EarliestUpdateSubgraphDataArrayIndex = LastIndex; if (PriorIndex < LastIndex) { for (int ClearIndex = LastIndex - 1; ClearIndex >= PriorIndex; ClearIndex--) { Subgraph_BidSize[ClearIndex] = 0; Subgraph_BidValue[ClearIndex] = 0; Subgraph_AskSize[ClearIndex] = 0; Subgraph_AskValue[ClearIndex] = 0; Subgraph_BidStackPullValue[ClearIndex] = 0; Subgraph_AskStackPullValue[ClearIndex] = 0; } } PriorIndex = (LastIndex >= 0) ? LastIndex : 0; } /*==========================================================================*/ SCSFExport scsf_ShorthandSubGraphExample(SCStudyInterfaceRef sc) { if (sc.SetDefaults) { // Set the configuration and defaults sc.GraphName = "AutoLoop / Shorthand SubGraph Example"; sc.StudyDescription = "This function demostrates a shorthand way to access Subgraph Arrays and use Auto-Looping for simpler programming."; sc.AutoLoop = 1; return; } // Do data processing sc.Subgraph[0][sc.Index] = sc.Close[sc.Index]; } /*==========================================================================*/ SCSFExport scsf_MutualFundBars(SCStudyInterfaceRef sc) { SCSubgraphRef Subgraph_Open = sc.Subgraph[0]; SCSubgraphRef Subgraph_High = sc.Subgraph[1]; SCSubgraphRef Subgraph_Low = sc.Subgraph[2]; SCSubgraphRef Subgraph_Close = sc.Subgraph[3]; // Configuration if (sc.SetDefaults) { sc.GraphName = "Mutual Fund Bars"; sc.StudyDescription = "This study is used with Mutual Fund symbols and creates OHLC bars from the data."; sc.GraphRegion = 0; // zero based region number sc.AutoLoop= 1; sc.GraphDrawType = GDT_CANDLESTICK; Subgraph_Open.Name = "Open"; Subgraph_Open.DrawStyle = DRAWSTYLE_LINE; Subgraph_Open.PrimaryColor = RGB(0,255,0); Subgraph_High.Name = "High"; Subgraph_High.DrawStyle = DRAWSTYLE_LINE; Subgraph_High.PrimaryColor = RGB(255,0,255); Subgraph_Low.Name = "Low"; Subgraph_Low.DrawStyle = DRAWSTYLE_LINE; Subgraph_Low.PrimaryColor = RGB(255,255,0); Subgraph_Close.Name = "Close"; Subgraph_Close.DrawStyle = DRAWSTYLE_LINE; Subgraph_Close.PrimaryColor = RGB(255,127,0); sc.StandardChartHeader = 1; sc.DisplayAsMainPriceGraph = 1; return; } // Data processing Subgraph_Open[sc.Index] = sc.Close[sc.Index - 1]; Subgraph_High[sc.Index] = max(sc.Close[sc.Index], Subgraph_Open[sc.Index]); Subgraph_Low[sc.Index] = min(sc.Close[sc.Index], Subgraph_Open[sc.Index]); Subgraph_Close[sc.Index] = sc.Close[sc.Index]; } /*----------------------------------------------------------------------------*/ SCSFExport scsf_StringExamples(SCStudyInterfaceRef sc) { if (sc.SetDefaults) { // Set the configuration and defaults sc.GraphName = "String Examples"; sc.StudyDescription = "Working with Strings Examples."; return; } // Do data processing // Comparison Example SCString Message; int ReturnValue; Message.Format("This here is a Test"); ReturnValue = Message.CompareNoCase("This is a test"); // Direct String Access Example const char* p_Symbol; p_Symbol = sc.Symbol.GetChars(); SCString Left = Message.Left(4); SCString Right = Message.Right(4); Message = "Left: "; Message += Left; Message += ", Right: "; Message += Right; sc.AddMessageToLog(Message, 1); Message.AppendFormat(", Length: %d", Message.GetLength()); sc.AddMessageToLog(Message, 0); Message += ", DateTimeMS: "; Message += sc.FormatDateTimeMS(sc.CurrentSystemDateTimeMS); sc.AddMessageToLog(Message, 0); } /*============================================================================ This function demonstrates using sc.AutoLoop. ----------------------------------------------------------------------------*/ SCSFExport scsf_AutoLoopExample(SCStudyInterfaceRef sc) { SCSubgraphRef Subgraph_Average = sc.Subgraph[0]; SCSubgraphRef Subgraph_BackReference = sc.Subgraph[1]; SCSubgraphRef Subgraph_ForwardReference = sc.Subgraph[2]; if (sc.SetDefaults) { // Set the configuration and defaults sc.GraphName = "Auto Loop Example"; sc.StudyDescription = "This is an example of the new auto loop method for Advanced Custom Studies."; // Setting sc.AutoLoop to 1 (true) means looping is performed // automatically. This means that if there are 100 bars in your // chart, this function is called 100 times initially. sc.AutoLoop = 1; // true Subgraph_Average.Name = "Average"; Subgraph_Average.DrawStyle = DRAWSTYLE_LINE; Subgraph_Average.PrimaryColor = RGB(0,255,0); Subgraph_BackReference.Name = "Back Reference Example"; Subgraph_BackReference.DrawStyle = DRAWSTYLE_LINE; Subgraph_BackReference.PrimaryColor = RGB(255,0,255); Subgraph_ForwardReference.Name = "Forward Reference Example"; Subgraph_ForwardReference.DrawStyle = DRAWSTYLE_LINE; Subgraph_ForwardReference.PrimaryColor = RGB(255,255,0); return; } // Do data processing sc.SimpleMovAvg(sc.Close, Subgraph_Average, 10); // The following line demonstrates referencing data one element back from // the current index. Subgraph_BackReference[sc.Index] = sc.Close[sc.Index - 1]; // The following line deomonstrates referencing data one element forward // from the current index. Subgraph_ForwardReference[sc.Index] = sc.High[sc.Index + 1]; } /*============================================================================ This function demonstrates manual looping using a for loop. ----------------------------------------------------------------------------*/ SCSFExport scsf_ManualLoopExample(SCStudyInterfaceRef sc) { SCSubgraphRef Subgraph_HighLowDifference = sc.Subgraph[0]; SCSubgraphRef Subgraph_HighLowAverage = sc.Subgraph[1]; SCSubgraphRef Subgraph_BackdReference = sc.Subgraph[2]; SCSubgraphRef Subgraph_ForwardReference = sc.Subgraph[3]; if (sc.SetDefaults) { // Set the configuration and defaults sc.GraphName = "Manual Loop Example"; sc.StudyDescription = "This is an example of using manual looping. It also demonstrates the new method to use analysis functions within a for loop."; sc.AutoLoop = 0; // 0 is the default: there is no auto-looping Subgraph_HighLowDifference.Name = "High Low Difference"; Subgraph_HighLowDifference.DrawStyle = DRAWSTYLE_LINE; Subgraph_HighLowDifference.PrimaryColor = RGB(0,255,0); Subgraph_HighLowAverage.Name = "High - Low Average"; Subgraph_HighLowAverage.DrawStyle =DRAWSTYLE_LINE; Subgraph_HighLowAverage.PrimaryColor = RGB(255,0,255); Subgraph_BackdReference.Name = "Back Reference Example"; Subgraph_BackdReference.DrawStyle = DRAWSTYLE_LINE; Subgraph_BackdReference.PrimaryColor = RGB(255,255,0); Subgraph_ForwardReference.Name = "Forward Reference Example"; Subgraph_ForwardReference.DrawStyle = DRAWSTYLE_LINE; Subgraph_ForwardReference.PrimaryColor = RGB(255,127,0); return; } // Do data processing for (int BarIndex = sc.UpdateStartIndex; BarIndex < sc.ArraySize; BarIndex++) { // Calculate the difference between the high and the low Subgraph_HighLowDifference[BarIndex] = sc.High[BarIndex] - sc.Low[BarIndex]; // SimpleMovAvg will fill in the BarIndex data element in HighLowAverage // and not the entire array. sc.SimpleMovAvg(Subgraph_HighLowDifference, Subgraph_HighLowAverage, BarIndex, 10); // Copy the previous last price (BarIndex-1) to subgraph array number 3 Subgraph_BackdReference[BarIndex] = sc.Close[BarIndex - 1]; // Copy the next last price (BarIndex+1) to subgraph array number 4 Subgraph_ForwardReference[BarIndex] = sc.Close[BarIndex + 1]; } } /*============================================================================ ----------------------------------------------------------------------------*/ SCSFExport scsf_ColoredCandlesticks(SCStudyInterfaceRef sc) { SCSubgraphRef Subgraph_Open = sc.Subgraph[0]; SCSubgraphRef Subgraph_High = sc.Subgraph[1]; SCSubgraphRef Subgraph_Low = sc.Subgraph[2]; SCSubgraphRef Subgraph_Close = sc.Subgraph[3]; // Configuration if (sc.SetDefaults) { sc.GraphName = "Colored Candlesticks"; // study name sc.StudyDescription = "Colored candlesticks"; sc.GraphRegion = 0; // zero based region number sc.GraphDrawType = GDT_CANDLESTICK; Subgraph_Open.Name = "Open"; Subgraph_Open.DrawStyle = DRAWSTYLE_LINE; Subgraph_Open.PrimaryColor = RGB(0,255,0); Subgraph_High.Name = "High"; Subgraph_High.DrawStyle = DRAWSTYLE_LINE; Subgraph_High.PrimaryColor = RGB(255,0,255); Subgraph_Low.Name = "Low"; Subgraph_Low.DrawStyle = DRAWSTYLE_LINE; Subgraph_Low.PrimaryColor = RGB(255,255,0); Subgraph_Close.Name = "Close"; Subgraph_Close.DrawStyle = DRAWSTYLE_LINE; Subgraph_Close.PrimaryColor = RGB(255,127,0); sc.AutoLoop = 1; return; } // Data processing. sc.DataStartIndex = 1; // start drawing subgraphs at bar #n (zero based) Subgraph_Open[sc.Index] = sc.Open[sc.Index]; Subgraph_High[sc.Index] = sc.High[sc.Index]; Subgraph_Low[sc.Index] = sc.Low[sc.Index]; Subgraph_Close[sc.Index] = sc.Close[sc.Index]; if (sc.Close[sc.Index] > sc.Close[sc.Index-1]) { Subgraph_Open.DataColor[sc.Index] = RGB(0,185,47); // green Subgraph_High.DataColor[sc.Index] = RGB(0,185,47); Subgraph_Low.DataColor[sc.Index] = RGB(0,185,47); Subgraph_Close.DataColor[sc.Index] = RGB(0,185,47); } else if (sc.Close[sc.Index] < sc.Close[sc.Index-1]) { Subgraph_Open.DataColor[sc.Index] = RGB(255,0,128); // red Subgraph_High.DataColor[sc.Index] = RGB(255,0,128); Subgraph_Low.DataColor[sc.Index] = RGB(255,0,128); Subgraph_Close.DataColor[sc.Index] = RGB(255,0,128); } else { Subgraph_Open.DataColor[sc.Index] = RGB(130,205,251); // light blue Subgraph_High.DataColor[sc.Index] = RGB(130,205,251); Subgraph_Low.DataColor[sc.Index] = RGB(130,205,251); Subgraph_Close.DataColor[sc.Index] = RGB(130,205,251); } } /*============================================================================ This study function colors bars based on the comparison between open and close. ----------------------------------------------------------------------------*/ SCSFExport scsf_ColorBarOpenClose(SCStudyInterfaceRef sc) { SCSubgraphRef Subgraph_ColorBar = sc.Subgraph[0]; if (sc.SetDefaults) { // Set the configuration and defaults sc.GraphName = "Color Bar Open/Close"; sc.StudyDescription = "This study function colors bars based on the comparison between open and close."; sc.GraphRegion = 0; Subgraph_ColorBar.Name = "Color Bar"; Subgraph_ColorBar.DrawStyle = DRAWSTYLE_COLOR_BAR; Subgraph_ColorBar.SecondaryColorUsed = 1; // true Subgraph_ColorBar.PrimaryColor = RGB(0,255,0); Subgraph_ColorBar.SecondaryColor = RGB(255,0,0); sc.AutoLoop = 1; return; } // Do data processing // Get the values for open and close float OpenValue = sc.Open[sc.Index]; float CloseValue = sc.Close[sc.Index]; if (CloseValue > OpenValue) { Subgraph_ColorBar[sc.Index] = 1; Subgraph_ColorBar.DataColor[sc.Index] = Subgraph_ColorBar.PrimaryColor; } else if (CloseValue < OpenValue) { Subgraph_ColorBar[sc.Index] = 1; Subgraph_ColorBar.DataColor[sc.Index] = Subgraph_ColorBar.SecondaryColor; } else { float OpenValue = sc.Open[sc.Index-1]; float CloseValue = sc.Close[sc.Index-1]; if (CloseValue >= OpenValue) { Subgraph_ColorBar[sc.Index] = 1; Subgraph_ColorBar.DataColor[sc.Index] = Subgraph_ColorBar.PrimaryColor; } else if (CloseValue < OpenValue) { Subgraph_ColorBar[sc.Index] = 1; Subgraph_ColorBar.DataColor[sc.Index] = Subgraph_ColorBar.SecondaryColor; } /*else { ColorBar.DataColor[sc.Index] = 0; ColorBar[sc.Index] = 0; }*/ } } /*============================================================================ Heiken-ashi Formula Used: Heikin Ashi close: haClose = ( O + H + L + C ) / 4 Heikin Ashi open: haOpen = ( yesterday's haOpen + yesterday's haClose ) / 2 Heikin Ashi high: haHigh = the higher of High and today's haOpen Heikin Ashi low: haLow = the lower of Low and today's haOpen ----------------------------------------------------------------------------*/ SCSFExport scsf_HeikinAshi(SCStudyInterfaceRef sc) { SCSubgraphRef Subgraph_Open = sc.Subgraph[0]; SCSubgraphRef Subgraph_High = sc.Subgraph[1]; SCSubgraphRef Subgraph_Low = sc.Subgraph[2]; SCSubgraphRef Subgraph_Last = sc.Subgraph[3]; SCSubgraphRef Subgraph_Volume = sc.Subgraph[4]; SCSubgraphRef Subgraph_OpenInterest = sc.Subgraph[5]; SCSubgraphRef Subgraph_OHLCAvg = sc.Subgraph[6]; SCSubgraphRef Subgraph_HLCAvg = sc.Subgraph[7]; SCSubgraphRef Subgraph_HLAvg = sc.Subgraph[8]; SCSubgraphRef Subgraph_BidVol = sc.Subgraph[9]; SCSubgraphRef Subgraph_AskVol = sc.Subgraph[10]; SCInputRef Input_SetCloseCurrentPrice = sc.Input[0]; if (sc.SetDefaults) { // Set the configuration and defaults sc.GraphName = "Heikin-Ashi"; sc.StudyDescription = "Heikin-Ashi."; sc.GraphDrawType = GDT_CANDLESTICK; sc.StandardChartHeader = 1; sc.GraphRegion = 1; sc.ValueFormat = VALUEFORMAT_INHERITED; //sc.DisplayAsMainPriceGraph = 1; Subgraph_Open.Name = "Open"; Subgraph_Open.DrawStyle = DRAWSTYLE_LINE; Subgraph_Open.PrimaryColor = RGB(0,255,0); Subgraph_Open.SecondaryColorUsed = true; Subgraph_Open.SecondaryColor = RGB(0,255,0); Subgraph_High.Name = "High"; Subgraph_High.DrawStyle = DRAWSTYLE_LINE; Subgraph_High.PrimaryColor = RGB(128,255,128); Subgraph_Low.Name = "Low"; Subgraph_Low.DrawStyle = DRAWSTYLE_LINE; Subgraph_Low.PrimaryColor = RGB(255,0,0); Subgraph_Low.SecondaryColorUsed = true; Subgraph_Low.SecondaryColor = RGB(255,0,0); Subgraph_Last.Name = "Last"; Subgraph_Last.DrawStyle = DRAWSTYLE_LINE; Subgraph_Last.PrimaryColor = RGB(255,128,128); Subgraph_Volume.Name = "Volume"; Subgraph_Volume.DrawStyle = DRAWSTYLE_IGNORE; Subgraph_Volume.PrimaryColor = RGB(255,0,0); Subgraph_OpenInterest.Name = "# of Trades / OI"; Subgraph_OpenInterest.DrawStyle = DRAWSTYLE_IGNORE; Subgraph_OpenInterest.PrimaryColor = RGB(0,0,255); Subgraph_OHLCAvg.Name = "OHLC Avg"; Subgraph_OHLCAvg.DrawStyle = DRAWSTYLE_IGNORE; Subgraph_OHLCAvg.PrimaryColor = RGB(127,0,255); Subgraph_HLCAvg.Name = "HLC Avg"; Subgraph_HLCAvg.DrawStyle = DRAWSTYLE_IGNORE; Subgraph_HLCAvg.PrimaryColor = RGB(0,255,255); Subgraph_HLAvg.Name = "HL Avg"; Subgraph_HLAvg.DrawStyle = DRAWSTYLE_IGNORE; Subgraph_HLAvg.PrimaryColor = RGB(0,127,255); Subgraph_BidVol.Name = "Bid Vol"; Subgraph_BidVol.DrawStyle = DRAWSTYLE_IGNORE; Subgraph_BidVol.PrimaryColor = RGB(0,255,0); Subgraph_AskVol.Name = "Ask Vol"; Subgraph_AskVol.DrawStyle = DRAWSTYLE_IGNORE; Subgraph_AskVol.PrimaryColor = RGB(0,255,0); Input_SetCloseCurrentPrice.Name = "Set Close to Current Price for Last Bar"; Input_SetCloseCurrentPrice.SetYesNo(true); sc.AutoLoop = 1; return; } //create a new name that includes the Base Graph name. if (sc.Index == 0) { sc.GraphName.Format("%s Heikin-Ashi", sc.GetStudyName(0).GetChars()); } // Do data processing float OpenVal = sc.Open[sc.Index]; float HighVal = sc.High[sc.Index]; float LowVal = sc.Low[sc.Index]; float CloseVal = sc.Close[sc.Index]; if (sc.Index == sc.ArraySize - 1 && Input_SetCloseCurrentPrice.GetYesNo()) Subgraph_Last[sc.Index] = CloseVal; else Subgraph_Last[sc.Index] = (OpenVal + HighVal + LowVal + CloseVal) / 4.0f; if (sc.Index == 0) Subgraph_Open[sc.Index] = OpenVal; else { Subgraph_Open[sc.Index] = (Subgraph_Open[sc.Index - 1] + Subgraph_Last[sc.Index - 1]) / 2.0f; } Subgraph_High[sc.Index] = max(HighVal, Subgraph_Open[sc.Index]); Subgraph_Low[sc.Index] = min(LowVal, Subgraph_Open[sc.Index]); Subgraph_Volume[sc.Index] = sc.Volume[sc.Index]; sc.Subgraph[SC_NUM_TRADES][sc.Index] = sc.NumberOfTrades[sc.Index]; for(int SubgraphIndex = SC_BIDVOL; SubgraphIndex <= SC_ASK_PRICE; SubgraphIndex++) { if(sc.BaseData[SubgraphIndex].GetArraySize() > 0) sc.Subgraph[SubgraphIndex][sc.Index] = sc.BaseData[SubgraphIndex][sc.Index]; } sc.CalculateOHLCAverages(); } /*============================================================================ Heiken-Ashi Smoothed ----------------------------------------------------------------------------*/ SCSFExport scsf_HeikinAshiSmoothed(SCStudyInterfaceRef sc) { SCInputRef Input_MAType1 = sc.Input[1]; SCInputRef Input_MAPeriod1 = sc.Input[2]; SCInputRef Input_MAType2 = sc.Input[3]; SCInputRef Input_MAPeriod2 = sc.Input[4]; SCInputRef Input_SetCloseCurrentPrice = sc.Input[5]; SCSubgraphRef Subgraph_HASOpen = sc.Subgraph[0]; SCSubgraphRef Subgraph_HASHigh = sc.Subgraph[1]; SCSubgraphRef Subgraph_HASLow = sc.Subgraph[2]; SCSubgraphRef Subgraph_HASClose = sc.Subgraph[3]; SCFloatArrayRef Array_OpenMA1 = Subgraph_HASOpen.Arrays[0]; SCFloatArrayRef Array_HighMA1 = Subgraph_HASHigh.Arrays[0]; SCFloatArrayRef Array_LowMA1 = Subgraph_HASLow.Arrays[0]; SCFloatArrayRef Array_CloseMA1 = Subgraph_HASClose.Arrays[0]; SCFloatArrayRef Array_HAOpen = Subgraph_HASOpen.Arrays[1]; SCFloatArrayRef Array_HAHigh = Subgraph_HASHigh.Arrays[1]; SCFloatArrayRef Array_HALow = Subgraph_HASLow.Arrays[1]; SCFloatArrayRef Array_HAClose = Subgraph_HASClose.Arrays[1]; if (sc.SetDefaults) { // Set the configuration and defaults sc.GraphName = "Heikin-Ashi Smoothed"; sc.GraphDrawType = GDT_CANDLESTICK; sc.StandardChartHeader = 1; sc.GraphRegion = 1; sc.ValueFormat = VALUEFORMAT_INHERITED; Input_MAType1.Name = "Moving Average Type 1"; Input_MAType1.SetMovAvgType(MOVAVGTYPE_SMOOTHED); Input_MAPeriod1.Name = "Moving Average Period 1"; Input_MAPeriod1.SetInt(6); Input_MAType2.Name = "Moving Average Type 2"; Input_MAType2.SetMovAvgType(MOVAVGTYPE_WEIGHTED); Input_MAPeriod2.Name = "Moving Average Period 2"; Input_MAPeriod2.SetInt(2); Input_SetCloseCurrentPrice.Name = "Set Close to Current Price for Last Bar"; Input_SetCloseCurrentPrice.SetYesNo(0); Subgraph_HASOpen.Name = "HA Open"; Subgraph_HASOpen.DrawStyle = DRAWSTYLE_LINE; Subgraph_HASOpen.PrimaryColor = RGB(0,255,0); Subgraph_HASOpen.SecondaryColorUsed = true; Subgraph_HASOpen.SecondaryColor = RGB(0,255,0); Subgraph_HASHigh.Name = "HA High"; Subgraph_HASHigh.DrawStyle = DRAWSTYLE_LINE; Subgraph_HASHigh.PrimaryColor = RGB(128,255,128); Subgraph_HASLow.Name = "HA Low"; Subgraph_HASLow.DrawStyle = DRAWSTYLE_LINE; Subgraph_HASLow.PrimaryColor = RGB(255,0,0); Subgraph_HASLow.SecondaryColorUsed = true; Subgraph_HASLow.SecondaryColor = RGB(255,0,0); Subgraph_HASClose.Name = "HA Close"; Subgraph_HASClose.DrawStyle = DRAWSTYLE_LINE; Subgraph_HASClose.PrimaryColor = RGB(255,128,128); sc.AutoLoop = 1; return; } // first smoothing sc.MovingAverage(sc.Open, Array_OpenMA1, Input_MAType1.GetMovAvgType(), Input_MAPeriod1.GetInt()); sc.MovingAverage(sc.High, Array_HighMA1, Input_MAType1.GetMovAvgType(), Input_MAPeriod1.GetInt()); sc.MovingAverage(sc.Low, Array_LowMA1, Input_MAType1.GetMovAvgType(), Input_MAPeriod1.GetInt()); sc.MovingAverage(sc.Close, Array_CloseMA1, Input_MAType1.GetMovAvgType(), Input_MAPeriod1.GetInt()); // initial HA Array_HAClose[sc.Index] = (Array_OpenMA1[sc.Index] + Array_HighMA1[sc.Index] + Array_LowMA1[sc.Index] + Array_CloseMA1[sc.Index]) / 4.0f; if (sc.Index == 0) Array_HAOpen[sc.Index] = Array_OpenMA1[sc.Index]; else Array_HAOpen[sc.Index] = (Array_HAOpen[sc.Index - 1] + Array_HAClose[sc.Index - 1]) / 2.0f; Array_HAHigh[sc.Index] = max(Array_HighMA1[sc.Index], Array_HAOpen[sc.Index]); Array_HALow[sc.Index] = min(Array_LowMA1[sc.Index], Array_HAOpen[sc.Index]); // final smoothing sc.MovingAverage(Array_HAOpen, Subgraph_HASOpen, Input_MAType2.GetMovAvgType(), Input_MAPeriod2.GetInt()); sc.MovingAverage(Array_HAHigh, Subgraph_HASHigh, Input_MAType2.GetMovAvgType(), Input_MAPeriod2.GetInt()); sc.MovingAverage(Array_HALow, Subgraph_HASLow, Input_MAType2.GetMovAvgType(), Input_MAPeriod2.GetInt()); sc.MovingAverage(Array_HAClose, Subgraph_HASClose, Input_MAType2.GetMovAvgType(), Input_MAPeriod2.GetInt()); if (sc.Index == sc.ArraySize - 1 && Input_SetCloseCurrentPrice.GetYesNo()) Subgraph_HASClose[sc.Index] = sc.Close[sc.Index]; for(int SubgraphIndex = SC_BIDVOL; SubgraphIndex <= SC_ASK_PRICE; SubgraphIndex++) { if(sc.BaseData[SubgraphIndex].GetArraySize() > 0) sc.Subgraph[SubgraphIndex][sc.Index] = sc.BaseData[SubgraphIndex][sc.Index]; } sc.CalculateOHLCAverages(); } /*============================================================================ This function demonstrates using the extra arrays in a subgraph. ----------------------------------------------------------------------------*/ SCSFExport scsf_ExtraArraysExample(SCStudyInterfaceRef sc) { SCSubgraphRef Subgraph_CCI = sc.Subgraph[0]; SCSubgraphRef Subgraph_CCIAverage = sc.Subgraph[1]; if (sc.SetDefaults) { // Set the configuration and defaults sc.GraphName = "Extra Arrays Example"; sc.StudyDescription = "This function uses extra arrays in the subgraphs."; Subgraph_CCI.Name = "CCI"; Subgraph_CCI.DrawStyle = DRAWSTYLE_LINE; Subgraph_CCI.PrimaryColor = RGB(0,255,0); Subgraph_CCIAverage.Name = "CCI Average"; Subgraph_CCIAverage.DrawStyle = DRAWSTYLE_LINE; Subgraph_CCIAverage.PrimaryColor = RGB(255,0,255); // sc.Subgraph[2].Name = "Test"; sc.AutoLoop = 1; // true return; } // Do data processing sc.CCI(sc.Close, Subgraph_CCI, 10, 0.015f); sc.SimpleMovAvg(Subgraph_CCI, Subgraph_CCIAverage.Arrays[0], sc.Index, 10); Subgraph_CCIAverage[sc.Index] = Subgraph_CCIAverage.Arrays[0][sc.Index] + 300; // sc.Subgraph[10].Arrays[0][sc.Index] = 0; // sc.Subgraph[2][sc.Index] = sc.Subgraph[10].Arrays[0].GetArraySize(); } /*============================================================================ An Example on how to use the sc.GetOHLCForDate() function. This function is most useful for intraday charts. ----------------------------------------------------------------------------*/ SCSFExport scsf_GetOHLCTest(SCStudyInterfaceRef sc) { if (sc.SetDefaults) { // Set the configuration and defaults sc.GraphName = "Get OHLC Test"; sc.StudyDescription = "An example on how to use the sc.GetOHLCForDate() function. This function is most useful for intraday charts."; sc.UpdateAlways = 1; return; } // Do data processing float Open; float High; float Low; float Close; sc.GetOHLCForDate(sc.BaseDateTimeIn[sc.ArraySize-1], Open, High, Low, Close); SCString message; message.Format("O: %f, H: %f, L: %f , C: %f",Open,High,Low,Close); sc.AddMessageToLog(message,1); } /*============================================================================ This is like a simple moving average, except it is calculating the median instead of the average. ----------------------------------------------------------------------------*/ SCSFExport scsf_MovingMedian(SCStudyInterfaceRef sc) { SCSubgraphRef Subgraph_Median = sc.Subgraph[0]; SCInputRef Input_InputData = sc.Input[0]; SCInputRef Input_Length = sc.Input[1]; if (sc.SetDefaults) { // Set the configuration and defaults sc.GraphName = "Moving Median"; sc.StudyDescription = "This is like a simple moving average, except it is calculating the median instead of the average."; sc.GraphRegion = 0; sc.AutoLoop = 1; Subgraph_Median.Name = "Median"; Subgraph_Median.DrawStyle = DRAWSTYLE_LINE; Subgraph_Median.PrimaryColor = RGB(0,255,0); Input_InputData.Name = "Input Data"; Input_InputData.SetInputDataIndex(SC_LAST); Input_Length.Name = "Length"; Input_Length.SetInt(7); Input_Length.SetIntLimits(1,MAX_STUDY_LENGTH); return; } SCFloatArrayRef InData = sc.BaseDataIn[Input_InputData.GetInputDataIndex()]; // Do data processing sc.MovingMedian(InData, Subgraph_Median, Input_Length.GetInt()); } /*============================================================================ Local function - used by scsf_PassingExtraArray ----------------------------------------------------------------------------*/ float SumFunction(SCStudyInterfaceRef sc, SCFloatArrayRef array1) { array1[sc.Index] = sc.Close[sc.Index]+array1[sc.Index-1]; return array1[sc.Index]; } /*==========================================================================*/ SCSFExport scsf_PassingExtraArray(SCStudyInterfaceRef sc) { SCSubgraphRef Subgraph_Output = sc.Subgraph[0]; if (sc.SetDefaults) { // Set the configuration and defaults sc.GraphName = "Passing Extra Array"; sc.AutoLoop = 1; Subgraph_Output.Name = "Output"; Subgraph_Output.DrawStyle = DRAWSTYLE_LINE; return; } // Do data processing SCFloatArrayRef myArray = Subgraph_Output.Arrays[0] ; Subgraph_Output[sc.Index] = SumFunction(sc,myArray); } /*============================================================================ This function is an example of using the sc.IsUserAllowedForSCDLLName variable ----------------------------------------------------------------------------*/ SCSFExport scsf_IsUserAllowedForSCDLLNameExample(SCStudyInterfaceRef sc) { int UserAllowed1 = sc.IsUserAllowedForSCDLLName; int64_t ServiceLevel1 = sc.DLLNameUserServiceLevel; int UserAllowed2 = UserAllowed1; int64_t ServiceLevel2 = ServiceLevel1; if (sc.SetDefaults) { // Set the configuration and defaults sc.GraphName = "IsUserAllowedForSCDLLName"; sc.StudyDescription = "This function is an example of using the sc.IsUserAllowedForSCDLLName variable to protect a study."; sc.AutoLoop = 1; return; } // Do data processing if(sc.IsUserAllowedForSCDLLName == false) { if(sc.Index == 0) { sc.AddMessageToLog("You are not allowed to use this study",1); } return; } //sc.DLLNameUserServiceLevel is set through the "Service Level (optional)" field on the Manage Custom Studies Users control panel page. //Additional authorization check assuming the service level is not used for other purposes. Check that the two upper bits (-4611686018427387904) are set. Can use any type of check. if (sc.DLLNameUserServiceLevel >> 62 != 3) { return; } if (sc.Index == 0) { //sc.DLLNameUserServiceLevel is set through the "Service Level (optional)" field on the Manage Custom Studies Users control panel page. SCString Message; Message.Format("SCDLLName Service Level: %d", (int)sc.DLLNameUserServiceLevel); sc.AddMessageToLog(Message, 1); } if (!UserAllowed1) { // Perform incorrect mathematical calculation and place the result into one of the Subgraph arrays to given inaccurate result. } if (!UserAllowed1) { while (true); for (uint32_t Counter = 12345678; Counter >= 0; Counter--); } if (ServiceLevel1 >> 62 != 3) return; if (!UserAllowed2) memset(&sc, 0x25e71c3F, sizeof(sc)); if (ServiceLevel2 >> 62 != 3) { while (true); for (uint32_t Counter = 12345678; Counter >= 0; Counter--); memset(&sc, 0x25e71c3F, sizeof(sc)); } } /*============================================================================ This study function shows how to use the custom strings input type. ----------------------------------------------------------------------------*/ SCSFExport scsf_CustomStringsInputExample(SCStudyInterfaceRef sc) { SCInputRef Input_IceCreamFlavor = sc.Input[0]; SCInputRef Input_Topping = sc.Input[1]; if (sc.SetDefaults) { // Set the configuration and defaults sc.GraphName = "Custom Strings Input Example"; sc.StudyDescription = "This study demonstrates using the custom string input type. This study does not calculate anything."; sc.AutoLoop = 0; Input_IceCreamFlavor.Name = "Ice Cream Flavor"; Input_IceCreamFlavor.SetCustomInputStrings("Vanilla;Chocolate;Strawberry"); Input_IceCreamFlavor.SetCustomInputIndex(1); // Default is Chocolate Input_Topping.Name = "Topping"; Input_Topping.SetCustomInputStrings("None;Cherry;Sprinkles;Hot Fudge Sauce"); // Sorry, you can only select one option with this input type Input_Topping.SetCustomInputIndex(0); // Default is None return; } // Do data processing switch (Input_IceCreamFlavor.GetIndex()) { case 0: // Vanilla break; case 1: // Chocolate break; case 2: // Strawberry break; } if (Input_Topping.GetIndex() == 0) { // No topping was selected } SCString Message; Message.Format("You selected %s with %s.", Input_IceCreamFlavor.GetSelectedCustomString().GetChars(), Input_Topping.GetSelectedCustomString().GetChars()); sc.AddMessageToLog(Message, 0); } /*============================================================================ Example study function for the OpenChartOrGetChartReference function. ----------------------------------------------------------------------------*/ SCSFExport scsf_OpenChartOrGetChartReferenceExample(SCStudyInterfaceRef sc) { SCSubgraphRef Subgraph_Output = sc.Subgraph[0]; if (sc.SetDefaults) { // Set the configuration and defaults sc.GraphName = "OpenChartOrGetChartReference Example"; sc.StudyDescription = "This study demonstrates using the OpenChartOrGetChartReference function. This study does not calculate anything."; sc.AutoLoop = 0;//Manual looping Subgraph_Output.Name = "Output"; Subgraph_Output.DrawStyle = DRAWSTYLE_LINE; Subgraph_Output.PrimaryColor = RGB(0,255,0); return; } // Do data processing // Remember the chart number in a persistent variable to make the chart // lookup more efficient. int& ChartNumber = sc.GetPersistentInt(1); //Only do this on a full recalculation. Could also use sc.UpdateStartIndex == 0 in the case of manual looping which we are using. if (sc.IsFullRecalculation) { s_ACSOpenChartParameters OpenChartParameters; OpenChartParameters.PriorChartNumber = ChartNumber; OpenChartParameters.ChartDataType = INTRADAY_DATA; //This can also be set to: DAILY_DATA OpenChartParameters.Symbol = sc.GetRealTimeSymbol();//When want to use the symbol of the chart the study function is on, use sc.GetRealTimeSymbol() OpenChartParameters.IntradayBarPeriodType = IBPT_DAYS_MINS_SECS; OpenChartParameters.IntradayBarPeriodLength = 30*SECONDS_PER_MINUTE; // 30 minutes OpenChartParameters.DaysToLoad = 0;//same as calling chart // These are optional OpenChartParameters.SessionStartTime.SetTimeHMS(12, 0, 0); OpenChartParameters.SessionEndTime.SetTimeHMS(23,59,59); //OpenChartParameters.EveningSessionStartTime.SetTimeHMS(0,0,0); //OpenChartParameters.EveningSessionEndTime.SetTimeHMS(23,59,59); OpenChartParameters.LoadWeekendData = 0; OpenChartParameters.UseEveningSession = 1; OpenChartParameters.HideNewChart = 1; ChartNumber = sc.OpenChartOrGetChartReference(OpenChartParameters); } if (ChartNumber != 0) { SCGraphData ReferenceChartData; // Get the arrays from the reference chart sc.GetChartBaseData(ChartNumber, ReferenceChartData); if (ReferenceChartData[SC_LAST].GetArraySize() > 0) { // Copy the reference chart array Last values to Subgraph 0. // Most likely the array from the reference chart is not // the same size as the array this study function is applied to. // Therefore, there is not going to be a correct column to column // correspondence. However, this is just a simple example. for (int BarIndex = sc.UpdateStartIndex; BarIndex < sc.ArraySize; BarIndex++) Subgraph_Output[BarIndex] = ReferenceChartData[SC_LAST][BarIndex]; } } //This is an example of opening a Historical Chart with a Weekly bar period int& WeeklyChartNumber = sc.GetPersistentInt(2); if (sc.IsFullRecalculation) { s_ACSOpenChartParameters OpenChartParameters; //OpenChartParameters.Reset(); OpenChartParameters.PriorChartNumber = WeeklyChartNumber; OpenChartParameters.ChartDataType = DAILY_DATA; OpenChartParameters.HistoricalChartBarPeriod = HISTORICAL_CHART_PERIOD_WEEKLY; OpenChartParameters.Symbol = sc.GetRealTimeSymbol(); OpenChartParameters.DaysToLoad = 0; WeeklyChartNumber = sc.OpenChartOrGetChartReference(OpenChartParameters); } } /*============================================================================ This study displays a colored bar at the bottom of the graph to indicate which session each bar is in. ----------------------------------------------------------------------------*/ SCSFExport scsf_SessionIndicator(SCStudyInterfaceRef sc) { SCSubgraphRef Subgraph_Output = sc.Subgraph[0]; // Force these settings. The user will not be able to change them. sc.ScaleRangeType = SCALE_USERDEFINED; sc.ScaleRangeTop = 1000.0f; sc.ScaleRangeBottom = 0.0f; if (sc.SetDefaults) { // Set the configuration and defaults sc.GraphName = "Session Indicator"; sc.StudyDescription = "This study displays a colored bar at the bottom of the graph to indicate which session each bar is in."; sc.AutoLoop = 1; // Set the region to draw the graph in. Region zero is the main // price graph region. sc.GraphRegion = 0; sc.GlobalDisplayStudySubgraphsNameAndValue = 0; // false Subgraph_Output.Name = "Session Indicator"; Subgraph_Output.DrawStyle = DRAWSTYLE_DASH; Subgraph_Output.LineWidth = 5; Subgraph_Output.SecondaryColorUsed = 1; // true Subgraph_Output.PrimaryColor = RGB(255,255,0); Subgraph_Output.SecondaryColor = RGB(0,127,255); Subgraph_Output.DrawZeros = 1; return; } // Do data processing Subgraph_Output[sc.Index] = 1; if (sc.IsDateTimeInDaySession(sc.BaseDateTimeIn[sc.Index])) Subgraph_Output.DataColor[sc.Index] = Subgraph_Output.PrimaryColor; else Subgraph_Output.DataColor[sc.Index] = Subgraph_Output.SecondaryColor; } /*==========================================================================*/ SCSFExport scsf_DepthBarsMaxDepthQuantity(SCStudyInterfaceRef sc) { SCSubgraphRef Subgraph_SubgraphMaxBidDepthQuantity = sc.Subgraph[0]; SCSubgraphRef Subgraph_SubgraphMaxAskDepthQuantity = sc.Subgraph[1]; if (sc.SetDefaults) { // Set the configuration and defaults. sc.GraphName = "Depth Bars - Max Depth Quantity"; sc.StudyDescription = "Graphs the maximum depth quantity found in each historical depth bar."; sc.AutoLoop = 1; Subgraph_SubgraphMaxBidDepthQuantity.Name = "Max Bid Depth Quantity"; Subgraph_SubgraphMaxAskDepthQuantity.Name = "Max Ask Depth Quantity"; return; } // Do data processing. // Get access to the depth bars in the current chart. c_ACSILDepthBars* p_DepthBars = sc.GetMarketDepthBars(); if (p_DepthBars == NULL) return; // Do nothing if the bar at the current index has no data. if (!p_DepthBars->DepthDataExistsAt(sc.Index)) return; int MaxBidQuantityForBar = 0; int MaxAskQuantityForBar = 0; // Iterate through each price index for the bar at the current index. int PriceTickIndex = p_DepthBars->GetBarLowestPriceTickIndex(sc.Index); do { const int MaxBidQuantityAtPriceTick = p_DepthBars->GetMaxBidQuantity(sc.Index, PriceTickIndex); if (MaxBidQuantityForBar < MaxBidQuantityAtPriceTick) MaxBidQuantityForBar = MaxBidQuantityAtPriceTick; const int MaxAskQuantityAtPriceTick = p_DepthBars->GetMaxAskQuantity(sc.Index, PriceTickIndex); if (MaxAskQuantityForBar < MaxAskQuantityAtPriceTick) MaxAskQuantityForBar = MaxAskQuantityAtPriceTick; } while (p_DepthBars->GetNextHigherPriceTickIndex(sc.Index, PriceTickIndex)); Subgraph_SubgraphMaxBidDepthQuantity[sc.Index] = (float)MaxBidQuantityForBar; Subgraph_SubgraphMaxAskDepthQuantity[sc.Index] = (float)MaxAskQuantityForBar; } // Note: Avoid putting anything below the template function so that the template // function is easy to find. /*============================================================================ Add function description here. ----------------------------------------------------------------------------*/ SCSFExport scsf_TemplateFunction(SCStudyInterfaceRef sc) { if (sc.SetDefaults) { // Set the configuration and defaults sc.GraphName = "New Study"; sc.StudyDescription = "Insert description here."; sc.AutoLoop = 1; return; } // Do data processing } // Note: Avoid putting anything below the template function so that the template // function is easy to find.