ACSIL Programming Concepts


This page documents various programming concepts for ACSIL (Advanced Custom Study Interface and Language).

Global Variables

In C++ it is possible to define global variables which are accesible from any of the study functions in your source code cpp file. Global variables should not be confused with Persistent Variables which are specific to each instance of a study on a chart.

There are generally 2 reasons why global variables would be used. 1. To share data between multiple study functions. 2. To maintain data between calls to your study function.

It is essential when using global variables that the study function sets sc.FreeDLL to FALSE (0) in the sc.SetDefaults code block at the top of the study function. If sc.FreeDLL is set to TRUE (1), then what you will find is that the global variables get reset every time the study function is called.

Global variables need to be at the top of your source code file and outside of your study function. Refer to the code example below.

Keep in mind that when a variable is global, there is only a single instance of it per DLL file. Therefore, multiple instances of a particular study or multiple study functions, are going to be sharing the very same instance of a global variable in the DLL it is defined within.

If you require basic variable types which are specific to each individual study instance, then you can store persistent data by using the functions to get and set persistent data.

If you require nonbasic variable types which are specific to each individual study instance and remain persistent between calls to a study function, then refer to Dynamic Memory Allocations Within Study Instance.

Code Example

#include "SierraChart.h"

//This is a global integer variable
int g_GlobalIntegerVariable;

SCSFExport scsf_StudyFunction(SCStudyInterfaceRef sc)
    if (sc.SetDefaults)
        sc.FreeDLL = FALSE;

System Studies

You are able to create, using the Advanced Custom Study Interface and Language, a System study. A System study is one in which gives you graphical, text and/or audible indication of buy and sell signals. This differs from an Automated Trading study which can also submit simulated or live orders.

The custom study interface is the same whether you create an indicator type Study or a System study. In the case of a Study you will put your formula results into a sc.Subgraph[].Data array or arrays that are graphed on the chart.

In the case of a System study you will fill the sc.Subgraph[].Data arrays with values indicating where you want to buy or sell at and use these together with the appropriate sc.Subgraph[].DrawStyle to indicate buy and sell conditions. For example, in the case of a System, you could set the sc.Subgraph[].Data array element for the bar you want to give a buy signal at, to the price at which you will buy. And set the sc.Subgraph[].DrawStyle to DRAWSTYLE_ARROWUP. If your study is displayed in Chart Region 1 ( sc.GraphRegion = 0;), then the Up Arrow will be shown at the price level you set the corresponding sc.Subgraph[].Data array element to.

If you require an audible or text indication of a buy or sell condition, then specify an Alert Condition Formula with your custom system study. For more information, refer to Alerts and Scanning. Or, you can add an alert message and play a sound directly from the study function using sc.SetAlert.

An example study function that acts as a System can be found in Systems.cpp inside the /ACS_Source folder inside of the folder that Sierra Chart is installed to.

Working With Text Strings and Setting Names

Some members of the Advanced Custom Study Interface (sc structure passed to your study function) use strings (a series of text characters internally implemented as a SCString). To set or modify these strings or names, to build your own formatted string, to compare strings, or to directly access strings, see the examples below. There is no need to have an understanding of the SCString class or the implementation details.

Setting A Name To A Constant String

Code Example

sc.GraphName = "My Study Graph";

Setting A Name To A Formatted String

You are able to be build text strings that contain numbers and other strings by using the Format() member function of the SCString class. The parameters of the Format() function work exactly like the C++ standard library printf() function. For reference on the printf() function, see the printf reference.

Code Example

// sc.GraphName will be set to the string created by the Format function
int ExampleNumber = 5;

sc.GraphName.Format("Example %d", ExampleNumber); 
SCString TestString;
float Value = 4.5;
TestString.Format("%s %.2f", "Value is:", Value);

Creating a Formatted String That Contains Another SCString

You will notice in the example below that we use the GetChars() function on the SCString to be able to access the internal C++ character pointer which is necessary when using the SCString Format() function. If we do not do this, it can lead to what is known as a CPU exception that you will see displayed in the Sierra Chart Message Log and additionally you will not get a properly formatted string.

Code Example

BarLabelText.Format("HL %s (%s)", ReversalPrice.GetChars(), LengthStr.GetChars()); 

Building a Character String for the sc.AddMessageToLog() or sc.AddAlertLine() Functions

If you want to add messages to the log using the sc.AddMessageToLog() or sc.AddAlertLine() functions, and have the messages contain variables, use a SCString and the Format() member function. The parameters of the Format() function work exactly like the C++ standard library printf() function. For reference on the printf() function, see this page.

Code Example

int MyInt = 50;

float MyFloat = 2.5f;
SCString Buffer;
Buffer.Format("My integer is %d -- and my float is: %f", MyInt, MyFloat);


Using a Formated String With The Text Tool

If you want to use the text tool to display text that contains variables, use the Format() member function. The parameters of the Format() function work exactly like the C++ standard library printf() function. For reference on the printf() function, see this page.

Code Example

s_UseTool Tool;
Tool.Text.Format("High Value: %.3f",sc.BaseDataIn[SC_HIGH][123]);

How To Compare Strings

You can compare a SCString to another string using the SCString CompareNoCase(const char* String, int NumChars) or SCString CompareNoCase(SCString String, int NumChars) functions.

These functions compare String to the string in the SCString these functions are called from, using a case-insensitive comparison up to the first NumChars characters of the two strings.

If NumChars is left out, then the function compares all the characters of the two strings.

The function returns 0 if both strings are equal up to the given length, an integer < 0 if String is lexically less than the string in SCString, and an integer > 0 if String is lexically greater than the string in SCString.

Code Example

long Result;
Result = sc.Symbol.CompareNoCase("ABC");

SCString SymbolToCompare("ABC");
Result = sc.Symbol.CompareNoCase(SymbolToCompare); 

Directly Accessing a SCString

You can use the GetChars function to directly access a SCString. This function returns a pointer to a C++ char type.

Code Example

const char* p_Symbol;
p_Symbol = sc.Symbol.GetChars(); 

Date Text String Example

//This creates a text string with the date without any spaces
SCString DateText;
int  Year, Month, Day;
DateText.Format("%d%02d%02d", Year,Month,Day);

Formatting Value to Chart Value Format

//This creates a text string with the last trade price formatted according to the chart Value Format
SCString FormattedValue;
sc.FormatGraphValue(sc.BaseData[SC_CLOSE][sc.Index], sc.ValueFormat);

SCString += operator (Text String Concatenation)

You can use the SCString += operator to concatenate multiple text strings into a larger text string. Refer to the code example below.

Code Example

SCString ExampleText;
Text = "Dog";
Text += "and Lion"; 


To get the length of a text string contained within a SCString object, call GetLength function on it. Refer to the example below.

Code Example

SCString TextString;
TextString = "Hello";
int Length = TextString.GetLength(); // will be set to 5

Dynamic Graph Names

Suppose you want to change the name of your study or the name of a subgraph in your study to match an input value. Setting the name inside of the code block for setting the defaults will not work because the code inside of that code block only gets executed once. For a dynamic name, you will need to add some code outside of the code block for setting the defaults. Look at the example below to see how this is done.

Code Example

SCSFExport scsf_DynamicNameExample(SCStudyInterfaceRef sc)

    // Set configuration variables
    if (sc.SetDefaults)
        sc.Subgraph[0].Name = "Subgraph";

        sc.Input[0].Name = "Value";


    // Set the subgraph name to include the Value input
    // This must be outside the above if (sc.SetDefaults) code
    // block so that it gets executed every time
    sc.Subgraph[0].Name.Format("Value %f Subgraph", sc.Input[0].GetFloat());

    sc.GraphName.Format("%s - Close = %f",sc.Symbol.GetChars(),sc.BaseDataIn[SC_LAST][sc.ArraySize-1]);

    // Do data processing


Using or Referencing Study/Indicator Data in an ACSIL Function

In your custom study function you may need to work with the results of other studies/indicators, like a Moving Average or some other study. There are several methods to accomplish this.

  • Use one of the Intermediate Study Calculation Functions like sc.SimpleMovAvg. Refer to ACSIL Interface Members - Functions page for complete documentation for all of the available functions. This is going to be the cleanest and most organized way to do it as long as there is an Intermediate Study Calculation Function available for the particular study or indicator that you want calculated and to use the data of. The results of the study calculations do not have to be outputted to study Subgraph arrays which are graphed on the chart.
  • Add the study to the chart and then get the Study Subgraph data by using the sc.GetStudyArrayUsingID function. Use this method when there is no Intermediate Study Calculation Function available for the particular study or indicator that you want to calculate and use the data of. This is going to be the case when you are using studies developed by outside developers or are using Advanced Custom Studies that do not have an Intermediate Study Calculation Function.

    Once the study is added to the chart it can be hidden by enabling the Hide Study setting in the Study Settings window for the study.

    You may also want to use this method, if the study that you want to calculate and get the data of, is already on the chart.
  • Somewhat related to this is the ability to access the additional arrays, sc.Subgraph[].Arrays[][], from other studies on the chart. This can be done with the sc.GetStudyExtraArrayFromChartUsingID() function.
  • Access a persistent variable set in one study from another study. The functions for setting persistent variables are sc.GetPersistent*.

    The functions for getting the persistent variables in another study are scGetStudyPersistent*FromChart.
  • It is also supported to reference studies like a Color Bar Based on Alert Condition study. This study colors bars. Where it colors bars, the Subgraph element at the bar index that is colored, is set to a nonzero value (usually 1.0). It is supported to get the Subgraph array from that study by using the sc.GetStudyArrayUsingID function as explained above.

Referencing Data from a Sheet within a Spreadsheet

When using the Spreadsheet Study on a chart, the main price graph data and study data is outputted to a Sheet within a Spreadsheet window. There are also up to 60 Formula Columns on the Sheet which can contain formulas and display the results those formulas.

An Advanced Custom Study is able to access the formula results from those 60 formula columns at any row.

Each Sheet Formula Column corresponds to a Study Subgraph in the Spreadsheet Study. You are able to access the data from the Spreadsheet Study by using the Using Study/Indicator Data in an ACSIL Function methods.

The Spreadsheet Study is just like any other study on the chart and can have its data accessed by an Advanced Custom Study. In the Spreadsheet Sheet used by the Spreadsheet Study, Column K is accessible with the sc.Subgraph[0].Data Subgraph array, Column M is accessible with the sc.Subgraph[1].Data Subgraph array, and so on.

However, there is a special consideration involving Calculation Precedence.

It is necessary to set sc.CalculationPrecedence = VERY_LOW_PREC_LEVEL in the sc.SetDefaults code block in the study function referencing the Spreadsheet Study. It is also necessary to place the instance of the study referencing the Spreadsheet Study at the end of the list of studies in the Analysis >> Studies >> Studies to Graph list.

Making Function Calls to External DLLs

You can call DLL functions in an external DLL file from an Advanced Custom study. The functions you will use to accomplish this are the Windows functions LoadLibrary and GetProcAddress. This is discussed on the Using Run-Time Dynamic Linking page on the MSDN website.

The recommended method with handling the loading of the library is to define a global HMODULE variable at the top of your source code file outside of a study function. If it defined is outside of a study function, it will be global. HMODULE is the type returned by LoadLibrary(). In your study function, if this variable is 0 or NULL, then make a call to LoadLibrary() and then set the HMODULE global variable with the handle. Otherwise, the library is already loaded and you can use the global HMODULE variable when you call GetProcAddress(). There is no need to free the library because that will be done when Sierra Chart is exited.

Passing ACSIL Interface Members Structure To Secondary Function

It is possible to call a secondary function from your primary study function and have it be able to access all of the ACSIL sc interface members. To do this you just need to pass the sc object by reference as demonstrated in the code below.

Code Example

void PassingSCStrutureExampleFunction(SCStudyInterfaceRef sc)
	//The "sc" structure can be used anywhere within this function.

"An example of calling a function that receives the Sierra Chart ACSIL structure (sc)."
SCSFExport scsf_PassingSCStrutureExample(SCStudyInterfaceRef sc)
	if (sc.SetDefaults)
		// Set the configuration and defaults
		sc.GraphName = "Passing sc Structure Example Function";
		sc.StudyDescription = "An example of calling a function that receives the Sierra Chart ACSIL structure (sc).";

		//During development set this flag to 1, so the DLL can be modified. When development is completed, set it to 0 to improve performance.
		sc.FreeDLL = 0;
	// Do data processing

	// The definition of the function called below must be above this function.a

Dynamic Memory Allocations Within Study Instance

Within an instance of an Advanced Custom Study, it is possible to dynamically allocate memory which remains persistent between study function calls. The code example below demonstrates this.

The code allocates the memory when it sees that the allocation does not exist and releases the memory when the study instance is removed from the chart or the Chartbook is closed.

When Sierra Chart is browsing through all of the studies in the DLL file in order to provide a listing of them, it needs to call the study function with sc.SetDefaults set to 1 but the study function should not be doing anything because Sierra Chart only needs to get the sc.GraphName. For this reason, the allocation of memory must never be done in the sc.SetDefaults code block.

Code Example

SCSFExport scsf_DynamicMemoryAllocationExample(SCStudyInterfaceRef sc)
	if (sc.SetDefaults)
		// Set the configuration and defaults

		sc.GraphName = "Dynamic Memory Allocation Example";

		sc.AutoLoop = 1;

		// This can be set to either 1 or 0. It does not matter in this case.
		sc.FreeDLL = 0;


	// Do data processing
	double * p_DoubleArray = (double*)sc.GetPersistentPointer(1);

		if(p_DoubleArray != NULL)
			sc.FreeMemory( p_DoubleArray);
			sc.SetPersistentPointer(1, NULL);


	if(p_DoubleArray == NULL)
		//Allocate an array of 1024 doubles.
		p_DoubleArray = (double *) sc.AllocateMemory( 1024 * sizeof(double) );

		if(p_DoubleArray != NULL)
			sc.SetPersistentPointer(1, p_DoubleArray);

	//assign value to one of the elements
	p_DoubleArray[0] = 100;


Alternative Method: Getting and Setting Persistent Data

As an alternative to dynamic memory allocations, there is also the ability to store persistent data of various simple types by using the functions to get and set persistent data.

Allocating Memory for Classes

When allocating memory for class types which use constructors and destructors, it is necessary to use the C++ functions new and delete instead of the sc.AllocateMemory and sc.FreeMemory functions. Refer to the code example below.

When using new and delete in the study function it is necessary to set sc.FreeDLL = 0. This is mandatory, otherwise exceptions will occur.

Code Example

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

    sc.GraphName = "Dynamic Memory Allocation Example (new/delete)";

    sc.AutoLoop = 1;

    // This must be set to 0 when using new and delete in a study function.
    sc.FreeDLL = 0;


//Example class
class ClassA
    int IntegerVariable;

// Do data processing
 ClassA * p_ClassA = (ClassA *)sc.GetPersistentPointer(1);

    if(p_ClassA != NULL)
        delete p_ClassA;
        sc.SetPersistentPointer(1, NULL);


if(p_ClassA == NULL)
    //Allocate one instance of the class
    p_ClassA = (ClassA *) new ClassA;

    if(p_ClassA != NULL)
        sc.SetPersistentPointer(1, p_ClassA);

int IntegerVariable = p_ClassA->IntegerVariable;


Study and Related Functions for Requesting Remote Data for Trading Levels

For a working code example to request trading levels from a remote server and display them on a chart, refer to the scsf_TradingLevelsStudy() function in the /ACS_Source/RequestValuesFromServerAndDraw.cpp file. This is only available with version 1227 and higher.

The study function is designed to work with data on the server in the following format:

2014/01/01, 1, 2, 3, 4, 5, 6, 7, 8
2014/01/02, 1, 2, 3, 4, 5, 6, 7, 8

One Time Calculations That Do Not Run During Study Updating

If there are calculations or other program statements you want to run only once in a study function and not every time the study is updated, then check sc.Index == 0. Refer to code below. With this check, any code within the "if" block will only run when the study is fully recalculated. A full recalculation occurs under various conditions, like when a study is added to the chart, or when a Chartbook is opened. During normal study updating, the code will not run.

if(sc.Index == 0)
    //Code to run only on study full recalculation

One Time Processing per Bar in the Chart

//This demonstrates a simple method to prevent processing on a bar more than once. 
//All bars in the chart other than the last one are only going to have processing for them in a study function, only once. 
//However, the last bar in the chart could be multiple times during real-time updating and during a chart replay.

int &LastBarIndexProcessed = sc.PersistVars->i1;
if (sc.Index == 0)
    LastBarIndexProcessed = -1;

if(sc.Index == LastBarIndexProcessed)

LastBarIndexProcessed = sc.Index;

Accessing Milliseconds

The internal value held within a SCDateTime variable may contain a millisecond value. For example, when a chart is set to 1 tick per bar or when the chart bars are not based upon a fixed amount of time, like when they are based upon a Number of Trades or Volume, the starting time of the bar may contain milliseconds.

Therefore, the sc.BaseDateTimeIn[] array Date-Time values can contain milliseconds.

Use the SCDateTime::GetMilliSecond() and SCDateTime::GetDateTimeYMDHMS_MS functions to get the milliseconds.

Custom Subgraph Coloring

ACSIL supports custom coloring study Subgraphs at each chart column/bar. This is accomplished by setting a custom RGB value through the sc.Subgraph[].DataColor[] array.

Generally it is a good idea to make the colors selectable through the Study Settings for the study. Each study Subgraph supports 2 color settings. There is the default Primary color button and the optional Secondary color button. To enable the Secondary color button, use sc.Subgraph[].SecondaryColorUsed. These color buttons for each study Subgraph set the sc.Subgraph[].PrimaryColor and sc.Subgraph[].SecondaryColor RGB values. These RGB color values can be directly used when setting the sc.Subgraph[].DataColor[] array.

Limiting Study Access to Particular Chartbook and Symbol

A study function can be programmed to prevent it from being used on a Chartbook other than the one specified. Or, from being used on a Symbol other than the one specified. Below are code examples of how this can be accomplished.

//This is an example to prevent a study from being used on a Chartbook other than the one specified
if(sc.ChartbookName != "Chartbook50")

//This is an example to prevent a study from being used on a symbol other than the one specified
if(sc.Symbol != "ABCD")

Finding Chart Bar Data Array Index for Start of Day

The following code will determine the index into the sc.BaseData[][] and sc.Subgraph[].Data[] arrays which is the start of the day based on the Session Times set for an Intraday chart, for the current bar index being processed.

// Bar index of beginning of trading day for bar at current index. This depends upon auto looping being true. 
SCDateTime DayStartDateTime =sc.GetTradingDayStartDateTimeOfBar(sc.BaseDateTimeIn[sc.Index]); 
int StartOfDayIndex= sc.GetContainingIndexForSCDateTime(sc.ChartNumber, DayStartDateTime);

Custom Free Form Drawing into Chart Window Directly

Through the Windows GDI, Graphics Device Interface, it is possible to draw freely into a chart window.

For a code example demonstrating how this is done, refer to the /ACS_Source/GDIExample.cpp file in the folder where Sierra Chart is installed to on your system.

We recommend using Visual C++ when creating DLL functions which use the Windows GDI.

Windows GDI documentation.

When using this feature, you need to define a drawing function which does the drawing using the Windows GDI. This drawing function is called when Sierra Chart draws on the chart, the study which has referenced that drawing function. This will only occur after there has been a call to the main "scsf_" study function.

The drawing function that you define has complete access to the ACSIL sc. structure. However, any changes to the variable members of that structure will have no effect.

Scale Related ACSIL Variables

The scale for a study graph and also for the base graph in the chart can be controlled with various ACSIL variables. They are listed below.

Accessing Volume at Price Data Per Bar

Studies like Numbers Bars and Volume by Price use the Volume at Price data available for each chart bar. To programmatically access this data in your own studies, it is necessary to use the Advanced Custom Study/System Interface and Language (ACSIL).

In the ACSIL study function, it is necessary to use the interface structure member sc.VolumeAtPriceForBars to access the volume at price data per bar.

Not Performing Calculation/Processing during Historical Data Downloading or Full Recalculation

To not perform any processing or calculations in an ACSIL custom study, include the following line before the code that does the processing or calculations. However, this needs to be after the sc.SetDefaults code block.

if (sc.IsFullRecalculation || sc.DownloadingHistoricalData)

For more information, refer to sc.IsFullRecalculation and sc.DownloadingHistoricalData.

Not Allowing Changes to Study Subgraph Settings

To not allow any changes to Study Subgraph settings through the Subgraphs tab of the Study Settings window for an ACSIL study, simply set those particular settings on the sc.Subgraph[] object outside of and after the sc.SetDefaults() code block in the study function.

Not all of the sc.Subgraph[] default settings which are normally in the sc.SetDefaults() code block, need to be outside of and after this code block. Only the ones you do not want to be changed by the user interface.

Converting Date-Time in One Time Zone to The User Set Time Zone

There are cases where an Advanced Custom Study may work with a particular Time in one time zone and need to convert it to the Time Zone set by the user in their copy of Sierra Chart. It is necessary for this Time to convert also have a Date so it is possible to apply the Daylight Savings time rules. So it is possible to convert a complete SC DateTime value.

The ACSIL function to convert a Date-Time in one time zone to the Time Zone that the user has set in their copy of Sierra Chart is sc.ConvertToSCTimeZone().

Skipping Bars/Columns with a Subgraph Draw Style

To draw a Study Subgraph where there are some bars/columns where there is no drawing of the particular Draw Style the Study Subgraph uses, requires that a Draw Style be used which supports interruption like one of the following:


And it is necessary to set sc.Subgraph[].DrawZeros = 0 for the Subgraph. Where you do not want to have the Draw Style drawn, simply set the sc.Subgraph[].Data[] element at that index to 0.

Refer to the code example below.

Code Example

FirstSubgraph.Name = "First Subgraph";
FirstSubgraph.DrawZeros = 0;
FirstSubgraph.PrimaryColor = RGB(0,255,0);

Detecting New Bars Added to Chart

Code Example

int& PriorArraySize = sc.GetPersistentInt(1);

//This is not a full recalculation of the study
if (!sc.IsFullRecalculation)
    // If there are new bars added
    if (PriorArraySize < sc.ArraySize)
        // put processing here that is required for when new bars are added to the chart

PriorArraySize = sc.ArraySize;

Performing Action When Certain Time is Encountered in Most Recent Chart Bar

The below example code demonstrates performing an action when a certain time is encountered in the most recent chart bar. It uses the sc.IsDateTimeContainedInBarIndex function.

The complete example can be found in the scsf_ActionWhenTimeEncountered function in the /ACS_Source/studies5.cpp file in the folder Sierra Chart is installed to.

Code Example

SCDateTime TimeToCheckFor;

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

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

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

Accessing Current Symbol Data for Other Symbols

To access current quote and real-time data for other symbols compared to the symbol of the chart a study instance is applied to, then the following functions can be used for this:

These functions are not for historical data access. They are intended for accessing the current quote and real-time data for other symbols. They allow for very efficient access to data in the case where you want to access data for a very large number of symbols.

You may also want to use sc.UpdateAlways to cause your study function to be continuously called to allow it to access the data at regular intervals.

If you want to use this capability to monitor the real-time data for a large number of symbols, then you will need to be using a data feed which is capable of providing data for a large number of symbols simultaneously. The Sierra Chart Exchange Data Feed is capable of this but a custom quotation has to be provided if you require data for more than 500 symbols concurrently. As a general rule we would expect the cost to be 10 USD per 100 symbols. For a quotation, contact Sierra Chart Support on the Support Board. Also, when tracking a large number of symbols with the Sierra Chart Exchange Data Feed we recommend using Low Bandwidth Mode.

ACSIL Chart Drawings and Hiding a Study

When a study is hidden through the Study Settings for the study, Chart Drawings added by the custom study will still be visible.

If you do not want the Chart Drawings visible in this case, then it is necessary to check the value of the sc.HideStudy variable and only draw the Chart Drawings if it is set to 0.

Code Example

if (!sc.HideStudy)
    //Add Chart Drawings here

Getting Index of Start of Trading Day in Intraday Chart

The following code example demonstrates how to get the bar index in the chart the study function is applied to, which corresponds to the start of the trading day in an Intraday chart. The start of the day is based upon the Session Times.

Code Example

//Get index of start of trading day based upon Date-Time at current index. This code assumes automatic looping.
SCDateTime StartDateTime = sc.GetTradingDayStartDateTimeOfBar(sc.BaseDateTimeIn[sc.Index]);
int StartBarIndex = sc.GetContainingIndexForSCDateTime(sc.ChartNumber, StartDateTime);

*Last modified Monday, 10th October, 2016.