Hi I'm starting two threads on steps to get started using Sierra Charts Advanced Custom Study/System Interface and Language (ACSIL).
This thread I would like to keep just for examples and steps to producing your own Custom Studies and Trading systems in SC. And another thread for questions about the examples in this thread.
To start I recommend setting up MS Visual Studio to program in. You can write the C++ files in Notepad++ as a minimum and compile as per these directions from Sierra Chart but you will miss out on a lot of the programming tools, error reporting and auto filling that's available with a modern IDE.
So first steps download Visual Studio Community version, https://visualstudio.microsoft.com/downloads/
(Its a big and bloated download)
You need to check the "Desktop development with C++" tools to include with the download but if not you can add them after install by going,
Tools>Get Tools And Features.. and the select them like in this pic and follow the modify/downloads and install instructions.
The following 21 users say Thank You to Trembling Hand for this post:
Ok once MS VS is installed start it and select "Create a new project",
Step 1. Then in the search box type "dll"
Step 2. Select Dynamic-Link Library (DLL). Be careful to select the right one as there a few similar types.
Step 3. Hit "Next"
Next give the Project a name. "SC_ACSIL_Examples". Use the same as me to make it easy to follow the next steps .
And save the project to a folder that makes sense to you. (remember where)
Then hit "Create"
That will create a project with a heap of files and dependencies that you do not need so I delete everything but whats needed. As per the pic below hold down "Ctrl" key and select "framework.h","pch.h","SC_ACSIL_Examples.h","ddlmain.cpp',"pch.cpp","cpp.hint". Making sure NOT to delete the "SC_ACSIL_Examples.cpp" file. Thats the one we program in.
Then go Project>SC_ACSIL_Examples Properties.. then,
Step1. Make sure in the Configurations drop box you have All Configurations selected
Step 2. Put in "C:\SierraChart\Data\" or you corresponding SC Data folder in the output directory
Step 3. Make sure Configuration Type is Dynamic Library (.dll)
click apply
Then Go to
Step 1. C/C++ > General
Step 2. Under "Additional Include Directories"
Step 3 Add "C:\SierraChart\ACS_Source"
Finally go to C/C++ >"Precompiled Headers"
And select "Not Using Precompiled Headers"
Hit Apply and then OK And thats now setup to start programming.
The following 8 users say Thank You to Trembling Hand for this post:
Open the "SC_ACSIL_Examples.cpp" file in in the main window of MSVS. If you are lost go,
View>Solution Explorer>SC_ACSIL_Examples>Source Files> double click on "SC_ACSIL_Examples.cpp"
Make sure you have Release and x64 selected as per the pic. This is very important. This will make a 64 bit dll. If you make a 32 bit dll SC will not reckonise it (as SC is now 64 bit only).
Again make sure you have x64 selected as per step 1
Then at
SCDLLName("Custom Study DLL")
change it to
SCDLLName("SC_ACSIL_Examples")
to keep it the same as my for this example. When you start producing your own you can name it whatever makes sense.
Then another important step change,
SCSFExport scsf_FunctionName(SCStudyInterfaceRef sc) to
SCSFExport scsf_SC_ACSIL_ExamplesV1(SCStudyInterfaceRef sc)
Making sure you don't delete or leave off the scsf. That is the function tag that SC searches all .dll in the data folder to see if there are study functions for it to load. Without that leading scsf SC will not load anything from our dll.
Now time to build
Go Build>Build Solution
If you have done all these steps perfectly in the output window you will see it start doing stuff and then finish with
========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ========== and a .dll file will be saved to your C:\SierraChart\Data\ like this,
If you open Sierra Chart and go Chart >Studies>Add Custom Study
You will/should see our SC_ACSIL_Examples study listed. As it stands it's useless at the moment as it does nothing but we have a start!
The following 6 users say Thank You to Trembling Hand for this post:
Please post any questions and problems or suggestions you have in this thread about my Sierra Chart ACSIL for Beginners to keep that thread reasonably concise and clean of tangents.
Thanks.
To keep this one clean with just examples
The following 4 users say Thank You to Trembling Hand for this post:
I'll come back tomorrow and start the actual programming part but as it stands up to this point if you have followed along correctly you will have a .dll in SC Data folder which is the complided study file with a few other files and a project folder that you created at the start somewhere probably in you Docs with the SC_ACSIL_Examples.cpp file and Microsoft Visual Studio project files. SC doesn't use these project or .cpp files only the .dll one you have built the project.
The following 7 users say Thank You to Trembling Hand for this post:
Ok so as it stands we have a framework for building any Sierra Chart study in this code we compile in MSVS.
The very first line of code always is
This brings into our study all the Sierra Chart structure as well as the Windows C++ Standard Library that we will be programming with. At the moment we don't really need to worry about that and just move on to the basics of ACSIL.
In the standard ACSIL Template Code there are three sections that different things are done in.
1. You declare any sc.Subgraph[] and sc.Input[].
sc.Subgraph[] are the arrays which will hold your study calculation and display them on your chart.
sc.Input[] are Inputs allowing user-specified inputs or parameters to a study function. Think for example a period setting for a moving average, like '20' for a 20 period or a Yes/No for a "Use even session Data" in your study.
2. Is where you set default setting for your studies Subgraph and Inputs.
These are the setting you see in the "Settings and inputs" & "Subgraphs" tabs when you open the "Study Settings" dialog box.
Like does a Subgraph display as a line or bar, what color is it etc.
Also in this section you set important study defaults like how it deals with data (Auto looping or manual), what Chart region is is set to etc.
3. Is where you do the actual programming to make calculations.
The following 7 users say Thank You to Trembling Hand for this post:
To start we will jump straight into accessing and display some data into the log and plotting a basic Subgraph. When writing studies its very helpful to have values you are accessing and calculation being printed to the log for de-bugging purposes.
First step in our ACSIL template is to declare a Subgraph to work with and a sc.Input
Just below the
Add,
Its important in C++ that every line of code is ended in a ";". That tells the compiler that its the end of that line of code so don't forget them.
Then on to the Study defaults. There are a few default settings that have to be set in every study.
Firstly you should set a study name and description and set whether or not the study uses Automatic looping or manual.[/URL] link( Don't worry about the details of that yet we'll come back to it) but just know its easier doing Automatic looping.
For now this is all you need to know,
" When your study function uses automatic looping, then it is automaticaly called once for every bar or column in the chart when the study is initially calculated. If there are 100 bars in the chart, then it will be called 100 times when your study is initially calculated. After that, the study function is called as the latest bar is updated and new bars are added. " https://www.sierrachart.com/index.php?page=doc/ACS_ArraysAndLooping.html
So In the sc.Setdefaults block we add,
As you can see there is a leading sc. to many lines of code. This is the ACSIL Interface Members Structure which comes from sierrachart.h that you included in the first line of code.
It's located in C:\SierraChart\ACS_Source folder and that why at the very start in the project properties you set that as an "include directory" so the compiler could find all the sc functions.
if you type sc. anywhere in the SCSFExport function block you will get a auto complete box with all the Sierra Chart ACSIL members and functions.
Above we declared a SCSubgraphRef (Which means Sierra Chart Subgraph Reference) "BarRange" and assigned it to sc.Subgraph[0]
Now we will set some display defaults for that,
Every Subgraph that you want to plot in your Study must have at a minimum .Name = "Some Name" otherwise it will not show up in Subgraph windows or on the chart.
Again if you type BarRange. an autofil box will popup and show you all the default setting you can set.
Here is the full list, https://www.sierrachart.com/index.php?page=doc/ACSIL_Members_scSubgraph.html
For now we will set the Drawstyle to DRAWSTYLE_BAR ( See more here) and the color to Blue. See examples here.
Now set the BarRangeMultiplier input defaults,
Again it needs a .Name so we will put
and we need to set a type and default value. This requires some forethought to make sure you are setting the right data type ie, int, float, Boolean, Date etc
You can see what you can set it to here, but we will set it to an Integer and give it a default value of 2
Its important that you have that
as the last line in the sc.SetDefaults Block or SC will crash when you try to add it to a chart.
So Now your full code should look like this,
And the complete code so far,
To check that so far you are on track. Make sure SC is closed. Go Build>Build Solution and in the output window of MSVS you sould see,
And then open sierra Chart and on a chart go Studies>Add Custom Study and select SC_ACSIL_ExamplesV1 and add to chart ad see if all is well.
Next step the calculations
The following 10 users say Thank You to Trembling Hand for this post:
To understand how to use chart data you have to understand how Bar data corresponds to arrays and indexing.
An array is a container object that holds a fixed number of values of a single type. Each value can be accessed by an index. The main arrays in SC are sc.BaseData[][] arrays contain the data for the main price graph in the chart. The sc.BaseData[][] arrays are used as input data to your study.
For example Close prices of each bar are stored in sc.BaseData[SC_LAST] or sc.Close[] (two names for the same thing). A few others are,
sc.BaseData[SC_OPEN] or sc.Open[]: The array of opening prices for each bar.
sc.BaseData[SC_HIGH] or sc.High[]: The array of high prices for each bar.
sc.BaseData[SC_LOW] or sc.Low[]: The array of low prices for each bar.
sc.BaseData[SC_VOLUME] or sc.Volume[]
Others are are listed here.
There are two other types of arrays in SC. You have already seen sc.Subgraph which you use to hold you study calculations and display data in. The other type of array available is sc.Subgraph[].Arrays[][] which are extra arrays available for extra study calculations and storing non-display data which we won't be using for now.
All these arrays store data as floats.
The only exception to that is sc.BaseDateTimeIn[] and sc.DateTimeOut[]
They are the starting and ending DateTime for each bar and are stored as SCDateTime data type which is a C++ double.
Now after all of that how do you use them? Well to access a value in an array you use the index (think Bar number). The indexes start at 0 for the first bar, the left most bar in the chart, and increment by 1 for each new bar.
So if you have a chart with 20 bars and want the Close price for the last bar, the twentieth, you would use the Close array index 19,
Rembering that the first bar index is 0 the second bar index is 1 and the third bar index is 2 up to the last bar being Index = (Number of bars - 1)
If you wanted the second last bars volume and had 20 bars you would so,
Now to make things easier Sierra Chart has an inbuilt function that makes it easier to access the Index of the array with Auto looping which we set in the sc.SetDefaults with this line sc.AutoLoop = 1; It enables us to return the last Index of the chart. Its sc.Index
So the above two lines of code become
Easiest way to visualize it is to imagine each array as a column in a spread sheet. As you can see instead of having to calculate how many bars are in the Chart you just use sc.Index as the last bar Index, sc.Index -1 as second last, sc.Index -2 as third last etc
The following 6 users say Thank You to Trembling Hand for this post:
To populate our Subgraph with our calculation which we want to do as bar range the code would be,
When your study function uses automatic looping, then it is automatically called once for every bar or column in the chart when the study is initially calculated. If there are 100 bars in the chart, then it will be called 100 times when your study is initially calculated. After that, the study function is called as the latest bar is updated and new bars are added.
So for each bar this code takes the High of that bar - the Low of the Bar and populates that into the correspond Index of the our SubGraph. Then resets sc.Index to the Index of the next Bar and so on till its at the last bar. Whenever a new bar is added sc.Index is incremented 1 bar Index.
To finish off this first example we are going to add some data to the log as a way of showing how to track values in your programming and use our as yet unused BarRangeMultiplier input. Which is very helpful when trying to figure out whats happening and what values to use.
From the link above you can see the that this is a sc. function and it takes the parameters of an SCString as the message you want printed and an int of either 0 or 1 to control how the log will activate.
So we have to declare an empty SCString then use another sc. function to Format that string with what we want to print to the log.
The way we do it is like this,
Which is fine but useless! We need to add some data from our Study. To do that we use string place holders. Such as %d for an int, %f for a float and %s for another string. In practice if we want to add the Bar index an int, Bar High a float, Bar low a float and Our calculated BarRange a float, it would look like this,
As you can see we have a line of text in the " " and various % place holders within that test where we want to put our data.
Then after our text we have the variables which we want to place in that text message. They will be placed in the same order as the % place holders. If you try and put a data type that not in the right type of place holder, for example a Float in an Int place holder, you will get weird numbers showing up and it wont make sense so be sure the data type matches the % type.
We haven't used our BarRangeMultiplier Input yet. we have set a valye to it in the defaults sections with the .SetInt() function and to use any Input you use the .GetInt() function. As you can see in the SC Docs here there are a whole lot of differant .Set() and .Get functions depending again on the data type you are using.
So just as a silly example as to how to use sc.Inputs lets just create another variable and add it to our above string that times our BarRange by our BarRangeMultiplier.
To do that we declare a new variable that will be a float, because we are multiply a float and int which will make a float. Then do the calculation.
Then to add that into our existing String we use another sc function .AppendFormat() which will add new text to the end of an excising.
Then fiinaly use that SCString in the sc.AddMessageToLog()
The following 6 users say Thank You to Trembling Hand for this post:
Here is our complete code with some comments in the programming section to explain each line,
Once you add the Study to a chart your log will print each something like this,
Noting how we added sc.Index as the first variable in our log and on each bar it increments up by one.
As well you can change the BarRangeMultiplier in the Subgraph "Settings and Inputs" section and note how it changes the value printed to log.
The following 9 users say Thank You to Trembling Hand for this post:
All that looks like a lot of work but actually its pretty simple.
Set up a Visual Studio .dll project and set the parameters for SC (Output directory, Include Directory, Set Not using Headers and delete un-needed files)
Paste the SC ACSIL template from here in the .cpp file.
Declare the Subgraphs you want to plot and the Inputs you'll need to control the Study
Set Defaults for you Study, Subgraphs and Inputs in sc.SetDefaults code block
Then program your calculations to produce the Study you wants.
The following 6 users say Thank You to Trembling Hand for this post:
Ok I'm going to do another rather simple example to expand on a few fundamentals then I'll start taking request.
Firstly when making a new Study we can, from here, start it in two ways. We could start a new VS project like in the first post and make a completely new study or we can just add another SCSFExport scsf_FunctionName(SCStudyInterfaceRef sc) function to our existing project. That way we can avoid having to set all the properties etc and we keep all the Examples ACSIL in one file and sub-menu in SC.
So remember the template for all SC ACSIL Studies.
When adding another study to an existing project you only need the code for the SCSFExport function code block. As we have already told the project to include "sierrachart.h" header file with all the SierraChart referances in the first line of our .cpp file and The SCDLLName("Custom Study DLL") is the name that SierraChart uses in Chart>Studies>Add Custom Studies list.
So below the very last curly bracket } of our SC_ACSIL_Examples .cpp paste the above bit of code without the first two lines. And change the study name scsf_FunctionName to scsf_SimpleMaExamples
Now this is very important. It MUST have the scsf_ at the start of the study name or SC when loading all the .dlls will skip it.
In the last Study we only had one SubGraph and one Study input. For this we will have multiple of each. So we need to declare each and give them a name.
Below the first { paste this code,
So we have now initiated and named 3 sc.Subgraph. As you can see that each sc.Subgraph has a differant index starting from 0. This is something to be sure not to get wrong because if you have two sc.Subgraph with the same index they will both hold the same values for the last calculation you do with them even if they have a different name. So always double check that they all have unique indexes. And the same applies to SCInputRef. They also need a unique index. You can have up to 60 Subgraph in one study and 128 SCInputRef.
The following 7 users say Thank You to Trembling Hand for this post:
Ok we have declared our required Subgraphs and Inputs now we have to set the Defaults for the Study and for each of our above Subgraphs and Inputs.
The first three lines of the if (sc.SetDefaults) code block deal with the general Study settings. sc.GraphName is self explanatory. sc.AutoLoop = 1; is the important one as it tells SC that the study uses auto looping. Generally for simple Studies you use Auto looping. as your studies become more complex or require extra control you would look to use manual looping but for now you should use stick with the easier to program auto looping and get a handle on the other parts of ACSIL. Yhen sc.GraphRegion = 0; sets the study default to display on the main chart region.
Now we move on to the individual Subgraphs. For each Subgraph at a minimum in the defaults you have to set a name, sc.Subgraph[0].Name If you don't set a individual name it will not be graphed in your study. You can still use it in the study to hold values and reference in calculations but it will effectively be hidden from the chart display. The other thing to be careful of is that you don't repeat names. As like the Subgraph indexes if they are not unique they will both hold the same values for the last calculation. In the code Docs you will also notice that they use the Subgraph index instead of the declared name value we set when declaring the Subgraphs. I think its much easier to read and follow using the names but just be aware that this,
is the same as this,
After we set each sc.Subgraph[0].Name we have to set the default Color, DRAWSTYLE and line width. There are as always with SC a heap of setting you can control, have a look here.
Thanks for this thread. I noticed that SC stopped maintaining VS solution and project templates so I was going to have to set that up myself for VS 2019.
Thanks for the valuable thread, and hope it can continue with trading system turorials.
How to import SC studies to be used in a trading system code ?
Should I import the whole code of that study in the new trading system code to use it?
I assume it is part of the SC library and we have the two lines at the front of the code to import it but it seems this is only working for ACSIL interface members that can be called by using sc.membername
Is there any sample code for importing studies?
The only examples in the ACS source is only for using sc.movingavg which is a member function of ACSIL and not a study ..
If I would like to import SCSFExport scsf_HighLowForTimePeriodExtendedLines(SCStudyInterfaceRef sc how to do this ..
I would appreciate anyone refer to me to a code example for trading systems that import other SC studies... I was doing this so easily in the spreadsheets but not sure how to do it in ACSIL ..
Hi guys been busy on a project so had to let this slide for a while.
I'll put up another example later today/tomorrow to show this but if you cannot wait you use one of these ACSIL functions to reference the array/s in a study on the same chart (scGetStudyArray) and/or different chart(scGetStudyArrayFromChart) and place the array/s you want to use in a SCFloatArray or Subgraph in your new Study.
sc.GetStudyArraysFromChart()
sc.GetStudyArraysFromChartUsingID()
EDIT (sorry about the lack of hyperlink this forum is dropping the end tag off the links??!!)
The following 3 users say Thank You to Trembling Hand for this post:
Thanks a lot for your prompt response Trembling Hand... I will stay tuned for your detailed example and thanks a lot for the thread... Kindly keep it alive here as it is my first day to find it and it has a lot of invaluable information...
Ok here is a quick and dirty example of using the arrays and input settings in a study to use as triggers for events in another study. This could be used for a trading system or another study. Using the requested scsf_HighLowForTimePeriodExtendedLines study it gets the two H/L arrays for the set time period from that study and puts them in local array SCFloatArray and it also gets the end time input for that study to check if that time has passed.
I've just used simple logic to print to the log but it would be the same to trigger for a trade. Basically it checks if the current bar start time is > or = to the ending time set in the HighLowForTimePeriod. Then checks once per bar if the close one bar ago is higher or lower than the H/L in the first study. If so prints out to the log the result.
Things to note.
Of course for this to work you need the scsf_HighLowForTimePeriodExtendedLines study on a chart and reference it as per the screen shot.
When referencing other studies you should set the sc.CalculationPrecedence to LOW_PREC_LEVEL or VERY_LOW_PREC_LEVEL to ensure that the first study has finished doing its calculations before using the values. Also note the logic that makes this study calculate just ONCE per new bar.
The following 4 users say Thank You to Trembling Hand for this post:
No rush at all... Just to let you know , I am patiently looking forward for your follow-up examples regarding importing an on chart-studies data to the trading system... Thanks a lot in advance and have a nice day ...
Thanks a lot for the comprehensive example. sorry, I am new to the forum and for some reason I didn't get a notification update by email. I will study the example, and post questions if any... Once again, thanks a lot for your prompt support and efforts. Highly appreciated indeed!
No have a look at the docs for that function and familiarise yourself with what zero indexing is.
"InputIndex: The zero-based index of the Input to get the value for. The Input index values + 1 are displayed in the Inputs list on the Study Settings window for the study. Example: (In:1)."
Again No. Have a look at what auto looping does in the docs. I covered it in post #8 of this thread but have a look in the docs. Its very important that you understand this - without auto looping you have to programmatically control the array indexes.
The following user says Thank You to Trembling Hand for this post:
int CurrentBarTime = sc.BaseDateTimeIn[sc.Index].GetTimeInSeconds();
if (Result > 0) //If there has been a successful order entry, then draw an arrow at the low of the bar.
{
Subgraph_BuyEntry[sc.Index-1] = sc.Low[sc.Index-1];
SignalString.Format("Buy Limit 1: %.2f & Buy Target1: %.2f & CurrentBarTime: %d", NewOrder.Price1, NewOrder.Price1+ NewOrder.Target1Offset, CurrentBarTime);
sc.AddMessageToLog(SignalString, 0);
}
This is a sample of what is printed in the message log:
How to print the CurrentBarTime to the Message log in <<Date, HH, MM, SS>> format -- I have coded it as above and it prints the time of the bar in numerical value of seconds which is not readable ?
How to print the CurrentBarTime to the Message log in <<Date, HH, MM, SS>> format -- I have coded it as above and it prints the time of the bar in numerical value of seconds which is not readable ?
In the Spreadsheet , there is inputs to enable trading within time range, i.e Trading start time , Trading End time. Is there ACSIL members to set these Inputs --
Should we add them to the set defaults code block only or we will need to use operators at the condition of the trade entry ?
In the Spreadsheet , there is inputs to enable trading within time range, i.e Trading start time , Trading End time. Is there ACSIL members to set these Inputs --
Should we add them to the set defaults code block only or we will need to use operators at the condition of the trade entry ?
Please keep this tread for the example I post so the thread remains concise and on topic. If you have an unrelated question to my examples please start another thread or ask in here.
Please post any questions and problems or suggestions you have in this thread about my Sierra Chart ACSIL for Beginners to keep that thread reasonably concise and clean of tangents.
Thanks.
The following user says Thank You to Trembling Hand for this post:
The only exception to that is sc.BaseDateTimeIn[] and sc.DateTimeOut[]
They are the starting and ending DateTime for each bar and are stored as SCDateTime data type which is a C++ double.
Wow! This is an error! I was googling sc.DateTimeOut[] in relation to custom bars and this thread came up at post #8! I was like huh?? That function, sc.DateTimeOut[] , is only for when you are setting the datetime of custom bars so why did I put it in a Beginners thread!!
Its the wrong function.
It should be sc.BaseDataEndDateTime[sc.Index] to access the the ending time of a bar.