Compile
LinPut Main Moculde FIRST - without trailing space:
"SwingBlastExt.cpp" "CalcLR.cpp"
"SCUtil.cpp"
Linear Regression calculated and shows to:
LR = Linear Regression Value (Magenta) SG9
SD High = Dev above LR (Red) SG10
SD Low = Dev below LR (Green) SG11
SCSubgraphRef lr = sc.Subgraph[8];\
SCSubgraphRef std_high = sc.Subgraph[9];\
SCSubgraphRef std_low = sc.Subgraph[10];\
|
void CalculateLinearRegressionEndChannel(SCStudyInterfaceRef sc, SCFloatArrayRef
lr, SCFloatArrayRef std_high, SCFloatArrayRef std_low, int lookback, float
number_of_deviations)
studies5.cpp:
SCSFExport scsf_LinearRegressionEndChannel(SCStudyInterfaceRef sc)
|
Copy SCFloatArray:
int (SCDLLCALL* GetStudyArrayUsingID)(unsigned int
StudyID, unsigned int StudySubgraphIndex, SCFloatArrayRef
SubgraphArray);
void InternalSetArray(T* DataPointer, int Size, int NumExtendedElements = 0)
SC_SUBGRAPHS_AVAILABLE = 128
typedef c_ArrayWrapper<float>& SCFloatArrayRef;
|
LinearRegr:
tempY = sc.BaseDataIn[SC_LAST][Index];
int ArraySize = sc.ArraySize;
|
void UpdateHHLL(SCStudyGraphRef sc, int length, SCFloatArray data, SCFloatArray
hh, SCFloatArray ll)
Input: Max=128, Inp[0]=05D96FC8/05D96FC8 Inp[1]=05D97088/05D97088 Inp[2]=05D97148/05D97148 | 2016-03-11 10:21:48
|
SCMain/sierrachart.h:
SCFloatArrayRef(SCDLLCALL* InternalPriceVolumeTrend)(SCBaseDataRef
BaseDataIn, SCFloatArrayRef Out, int Index);
SCFloatArrayRef PriceVolumeTrend(SCBaseDataRef
BaseDataIn, SCFloatArrayRef Out, int Index)
{ return InternalPriceVolumeTrend( BaseDataIn, Out, Index); }
SCFloatArrayRef PriceVolumeTrend(SCBaseDataRef
BaseDataIn, SCFloatArrayRef Out)
{ return InternalPriceVolumeTrend( BaseDataIn, Out, Index); }
SCSFExport scsf_PriceVolumeTrend(SCStudyInterfaceRef sc)
{
SCSubgraphRef PVT = sc.Subgraph[0];
sc.DataStartIndex = 1;
sc.PriceVolumeTrend(sc.BaseDataIn, PVT);
}
studies3.cpp: SCSFExport scsf_PositiveVolumeIndex(SCStudyInterfaceRef sc)
{
SCSubgraphRef PVI = sc.Subgraph[0];
float prev_PVI;
float prev_data;
float data;
float PVIval;
float volume;
float prev_volume;
sc.DataStartIndex = 0;
int pos = sc.Index;
if(pos == 0)// We are starting a new PVI study
{
PVI[0] = InitialValue.GetFloat();
pos++;
}
volume = sc.Volume[pos];
prev_volume = sc.Volume[pos-1];
prev_PVI = PVI[pos-1];
if(volume > prev_volume) // current volume less then equal to previous volume.
{
data = sc.BaseDataIn[InputData.GetInputDataIndex()][pos];
prev_data = sc.BaseDataIn[InputData.GetInputDataIndex()][pos-1];
PVIval = prev_PVI + ((data-prev_data) / prev_data * prev_PVI );
}
else
{
PVIval = prev_PVI;
}
PVI[pos] = PVIval;
}
|
SCString
Working
with Strings |
SCMain
Trading
SCMain/sierrachart.h:
int AllowMultipleEntriesInSameDirection;
int SupportReversals;
int SendOrdersToTradeService;
int AllowOppositeEntryWithOpposingPositionOrOrders;
int (SCDLLCALL* InternalBuyEntry)(s_SCNewOrder& NewOrder, int Index);
int (SCDLLCALL* InternalBuyExit)(s_SCNewOrder& NewOrder, int Index);
int (SCDLLCALL* InternalSellEntry)(s_SCNewOrder& NewOrder, int Index);
int (SCDLLCALL* InternalSellExit)(s_SCNewOrder& NewOrder, int Index);
int (SCDLLCALL* CancelOrder)(int InternalOrderID);
int (SCDLLCALL* GetOrderByOrderID)(int InternalOrderID, s_SCTradeOrder&
OrderDetails);
int (SCDLLCALL* GetOrderByIndex)(int OrderIndex, s_SCTradeOrder&
OrderDetails);
Position
struct s_SCPositionData
{
SCString Symbol;
int PositionQuantity;
double AveragePrice;
Order
struct s_SCNewOrder
{
int Version;
int OrderType;
unsigned int OrderQuantity;
double Price1;
double Price2;
int InternalOrderID;
int InternalOrderID2;
order.OrderType = SCT_MARKET;
order.OrderQuantity = inp_contracts.GetInt();
Order
Modify
Target1Offset, Stop1Offset, Target1Price, Stop1Price
|
SCMain Data
SCMain/sierrachart.h:
SCDateTimeArray BaseDateTimeIn; // From the base graph
SCFloatArrayArray BaseDataIn; // From the base graph
SCDateTimeArray DateTimeOut;
SCInput145Array Input;
typedef c_ArrayWrapper<s_SCInput_145> SCInput145Array;
typedef s_SCInput_145& SCInputRef;
class SCDateTimeArray : public c_ArrayWrapper<SCDateTime>
double DateTimeValue; // SCDateTime
SCDateTime BeginDateTime = BaseDateTimeIn[BarIndex];
|
c_ArrayWrapper<T>
template <typename T>
class c_ArrayWrapper
{
int GetArraySize() const { return
m_NumElements; }
const T* GetPointer() const { return
m_Data; }
}
|
Inputs:
SCInputRef inp_price_volume_trend = sc.Input[0]; \
SCInputRef inp_price_volume_index = sc.Input[1]; \
SCInputRef inp_lookback = sc.Input[2]; \
SCInputRef inp_contracts = sc.Input[3]; \
SCInputRef inp_enabled = sc.Input[4];\
SCInputRef inp_tws = sc.Input[5];\
SCInputRef inp_twe = sc.Input[6];\
SCInputRef inp_lr_length = sc.Input[7];\
SCInputRef inp_std = sc.Input[8];\
|
price_volume_index:
s_SCSubgraph_260 -> SCFloatArray Data; // Array of data values
float& operator [] (int Index) { return Data[Index];}
operator SCFloatArray& () { return Data; }
|
Entries:
Chart: Pietro_CLH6 10 Min #1 | Study: Swing Blast Test | Bar#02713: Long: 34.3800 | 2016-03-10 08:51:38
Chart: Pietro_CLH6 10 Min #1 | Study: Swing Blast Test | Bar#02757: Short: 35.7800 | 2016-03-10 08:51:38
Chart: Pietro_CLH6 10 Min #1 | Study: Swing Blast Test | Bar#02758: Short: 35.7200 | 2016-03-10 08:51:38
Chart: Pietro_CLH6 10 Min #1 | Study: Swing Blast Test | Bar#02759: Short: 35.9100 | 2016-03-10 08:51:38
Chart: Pietro_CLH6 10 Min #1 | Study: Swing Blast Test | Bar#02760: Short: 35.9600 | 2016-03-10 08:51:38
Chart: Pietro_CLH6 10 Min #1 | Study: Swing Blast Test | Bar#02765: Short: 35.9700 | 2016-03-10 08:51:38 |
|
Creating Custom Indicator
(C++)
Analysis/New Custom Studies - select CPP source file
and click OPEN
The C++ Editor will open
|
Define Your DLL Name:
#include "sierrachart.h"
SCDLLName("Custom Study DLL")
Defined in scstructures.h(53):
#define SCDLLEXPORT extern "C" __declspec(dllexport)
#define SCDLLCALL __cdecl
#define SCDLLName(DLLName) SCDLLEXPORT int SCDLLCALL
scdll_DLLVersion() { return SC_DLL_VERSION; }
SCDLLEXPORT const char* SCDLLCALL scdll_DLLName() { return DLLName; }
|
ZeroBased: All of Sierra Chart's arrays are zero based. That is, 1000 elements are
designated from 0-999 (For example, Data[0] to Data[999] instead of Data[1] to
Data[1000]). |
CustMovAvg Example:
CustMovAvg.cpp
#include "sierrachart.h"
SCDLLName("Custom Moving Avg DLL")
SCSFExport scsf_SimpMovAvg(SCStudyGraphRef sc)
{
if (sc.SetDefaults)
// During development set this flag to 1, so the DLL can be rebuilt without restarting Sierra Chart.
// When development is completed, set it to 0 to improve performance.
sc.FreeDLL = 1;
//sc.FreeDLL = 0;
...
}
int InMALength = sc.Input[0].GetInt(); // Input 0 - "Length"
sc.Subgraph[0].Data[sc.Index] = fRet;
|
Misc:
View Log: Message Log which is opened by selecting Window >> Show/Hide Message Log on the menu |
Add Log Messages: SCString Buffer; Buffer.Format("Short %d, Ret=%d",
numQty,nRet);
sc.AddMessageToLog(Buffer,0); |
Check for error + msg: int
nRet = sc.BuyEntry(NewOrder); if (Result <= 0) //order was
rejected
sc.AddMessageToLog(sc.GetTradingErrorTextMessage(nRet), 0); |
TAB: Notepad++ Set Tab to 4
|
Check Last bar: if
(sc.Index == sc.ArraySize -1) //if at the last bar (Maybe
works in Live - not historic) |
DateTime
Date is represented by the integer portion[number of days since December 30, 1899]
of this number and the Time[SecMidnight] is represented by the fractional portion of the number.
SCString Buffer;
SCDateTime dt = sc.BaseDateTimeIn[sc.Index];
int CurrentBarDate = dt.GetDate();
int CurrentBarTime = dt.GetTime();
int Year, Month, Day;
dt.GetDateYMD(Year, Month, Day);
int Hour, Minute, Second;
dt.GetTimeHMS(Hour, Minute, Second);
Buffer.Format("[%05d# %04d%02d%02d %02d:%02d] ....",sc.Index+1,Year, Month, Day, Hour, Minute,..);
DT=2008,02,15-15:45:00:[39493/56700]
|
|
|
MovingAvg Example:
SCSFExport scsf_SimpMovAvg(SCStudyGraphRef sc)
{
// Section 1 - Set the configuration variables and defaults
if (sc.SetDefaults)
{
sc.GraphName = "Moving Average";
sc.StudyDescription = "Example function for calculating a simple moving average from scratch.";
sc.AutoLoop = 1; // true
sc.FreeDLL = 0;
sc.GraphRegion = 0; // Set the Chart Region to draw the graph in. Region 0 is the main price graph region.
sc.Subgraph[0].Name = "Average"; //// Set the name of the first subgraph
sc.Subgraph[0].PrimaryColor = RGB(255,0,0); // Red // Set the color and style of the subgraph line.
sc.Subgraph[0].DrawStyle = DRAWSTYLE_LINE;
sc.Input[0].Name = "Length";
sc.Input[0].SetInt(30);
sc.Input[0].SetIntLimits(1, 1000);
return; // Must return before doing any data processing if sc.SetDefaults is set
}
// Data processing Everything below here is run on every chart update or when the chart is reloaded.
// Get the inputs
int InMALength = sc.Input[0].GetInt(); // Input 0 - "Length"
// Set the index of the first array element to begin drawing at.
// Setting the variable sc.DataStartIndex ensures that we start far enough
// from the beginning of the array to create valid plots.
sc.DataStartIndex = InMALength - 1;
// Calculate a simple moving average from the data in the input arrays
// InMALength is 30 by default. Therefore, the 1st data element plotted begins with element
// 29 (InMALength - 1). If there are 1000 bars in the chart, then the last data element
// plotted begins with element 970 (999 - (InMALength - 1)) and goes to element 999.
// Add together the closing prices over the length for the prior bars
float Sum = 0;
for (int InIndex = sc.Index - (InMALength - 1); InIndex <= sc.Index; ++InIndex)
{
// 'BaseDataIn[SC_LAST]' is the closing prices array for the chart
Sum = Sum + sc.BaseDataIn[SC_LAST][InIndex];
}
// 'sc.Subgraph[0].Data' is the output array for the moving average to be graphed.
// The Sum is divided by the Length to get the average
sc.Subgraph[0].Data[sc.Index] = Sum / InMALength;
} |
Custom
Custom Studies Overview
These interface members begin with sc. in the source code. This designates that the variable, function, or array is part of the Sierra Chart Advanced Custom Study Interface.
|
Compiling:
Analysis/Build Custom Studies DLL + Select *.cpp file +
click on "Build Custom Studies DLL":
- Starting build of Custom Studies Source files:
CustMovAvg.cpp. -- 11:43:43
"C:\SierraChart\CPPCompiler\bin\g++.exe"
"C:\SierraChart\ACS_Source\CustMovAvg.cpp" -march=i686 -mtune=i686 -O2 -shared
-static -static-libgcc
-static-libstdc++ -s -fno-rtti -fno-exceptions -std=gnu++11 -o
"C:\SierraChart\Data\CustMovAvg.dll"
-- End of Build -- 11:43:48
New DLL in: C:/SierraChart/Data/CustMovAvg.dll
scdll_DLLName
scdll_DLLVersion
scsf_SimpMovAvg
-shared = Produce a shared object which can then be linked with other objects to form an executable.
-static = On systems that support dynamic linking, this prevents linking with the shared libraries
|
Used custom study in Chart:
Analysis/Studies (F6) + Click on "Add Custom Study"
and navigate to DLL/Study:
Advanced Custom Study or a Study Collection |
Adding custom code:
Add custom includes BEFORE "sierrachart.h"
#include <time.h>
#include <fstream>
#include "sierrachart.h"
|
Debugging:
Detail
here - Visual Studio - Attach to Process (SierraChart) ...
|
Position
using s_SCPositionData pos.h
SCString Symbol;
int PositionQuantity;
double AveragePrice;
|
Orders
using smart
Order Entry logic pos.h
s_SCNewOrder::TimeInForce: SCT_TIF_DAY
+ SCT_TIF_GTC
Targets: s_SCNewOrder::Target1Offset etc
This specifies the offset for a Target Attached Order (1, 2, 3, 4, 5) to submit along with the parent order. This member only applies when using the sc.BuyEntry and sc.SellEntry Order Actions
Stops s_SCNewOrder::Stop1Offset
This specifies the offset for a Stop Attached Order (1, 2, 3, 4, 5) to submit along with the parent order. This member only applies when using the sc.BuyEntry and sc.SellEntry Order Actions.
Size:
s_SCNewOrder::OrderQuantity
This must be set to a nonzero positive number in the case of
sc.BuyEntry, sc.SellEntry, sc.BuyOrder, sc.SellOrder
OrderID:
s_SCNewOrder::InternalOrderID
int sc.GetOrderByOrderID(int
InternalOrderID, s_SCTradeOrder& OrderDetails);
GetOrderByIndex
[02713# 20160304 10:00]: Entry(1): ID=1265148, Dir= 1,
ATR= 0.095, TargetOff=0.14, StopOffset=0.19
[02713# 20160304 10:00]: Order: ID=1265148(P=0) Type=Market Sym=Pietro_CLH6 Qty=1 Avg=34.4300 Prc1/2=34.43/0.00
OrderList ID=1265148 (SCUtil_OrderList)
OrderList#4: Attached: [02713# 20160304 10:00]: Order: ID=1265149(P=1265148) Type=Limit Sym=Pietro_CLH6 Qty=1 Avg=0.0000 Prc1/2=34.57/0.00
OrderList#5: Attached: [02713# 20160304 10:00]: Order: ID=1265150(P=1265148) Type=Stop Sym=Pietro_CLH6 Qty=1 Avg=0.0000 Prc1/2=34.24/0.00
OrderList#6: Not Open: [02713# 20160304 10:00]: Order: ID=1265148(P=0) Type=Market Sym=Pietro_CLH6 Qty=1 Avg=34.4300 Prc1/2=34.43/0.00
|
Trading Systems
[Indicators]:
Trading
Examples ExampleTrdSystems
IB
IBSym
Google
Debug
BACKTESTING TradeSettings
Trading Strategies are called "automated trading functions"
- Orders are submitted through the sc.BuyEntry,
sc.BuyExit,
sc.SellEntry and
sc.SellExit trading functions
- using smart
Order Entry logic
Only real time updating or data added to the chart during a replay can cause order processing.
Tradespecific
variables are available. Some difference
between Live and Replay apply.
Orders are submitted through the sc.BuyEntry, sc.BuyExit, sc.SellEntry and sc.SellExit trading functions that process Buy Entries, Buy Exits, Sell Entries, and Sell Exits.
On historical bars and during a historical data download, these Entry and Exit Order Action functions are ignored
you can perform Back Testing by using Trade Simulation Mode and replaying the chart, or by performing a Bar Based Back Test.
A Bar Based Back Test uses the Open, High, Low, Close data of the loaded chart bars themselves to evaluate the automated trading system.
Backtesting:
Set Replay Mode to: "Accurate Trading System Back Test Mode"
It is this data which is incrementally added to the chart during the Back Test.
Orders use the s_SCNewOrder
structure: actual
quantity, Type(Limit,
Mkt etc), Price,
Example: TrdExample1.cpp
Changed only:
sc.FreeDLL = 1; //on top always
View all SIMULATED Trades: Save via File/Save As to C:/SierraChart/TradeActivityLogs/TradesList.txt

Statistics: Save via File/Save As to C:/SierraChart/TradeActivityLogs/TrdStats1.txt
Get only one open trade:
Trading Log seems OK:
MSFT 15 Min #1 | Trading CrossOver Example | Buy Entry reversal order processed. Flatten quantity: 1. New order quantity: 1 | Bar Start Time: 2007-09-06 14:15:00 | 2015-12-19 23:59:34
MSFT 15 Min #1 | Trading CrossOver Example | SellEntry reversal order processed. Flatten quantity: 1. New order quantity: 1 | Bar Start Time: 2007-09-07 11:00:00 | 2015-12-19 23:59:34
MSFT 15 Min #1 | Trading CrossOver Example | Buy Entry reversal order processed. Flatten quantity: 1. New order quantity: 1 | Bar Start Time: 2007-09-11 10:45:00 | 2015-12-19 23:59:34
Added messages to Regular Log:
MSFT 15 Min #1 | Study: Trading CrossOver Example | Buy 1, Ret=1 | 2015-12-19 23:59:37
MSFT 15 Min #1 | Study: Trading CrossOver Example | Sell 1, Ret=1 | 2015-12-19 23:59:37
MSFT 15 Min #1 | Study: Trading CrossOver Example | Buy 1, Ret=1 | 2015-12-19 23:59:37
MSFT 15 Min #1 | Study: Trading CrossOver Example | Sell 1, Ret=1 | 2015-12-19 23:59:37
Added GetTradePosition:
s_SCPositionData
PositionData; int nRet = sc.GetTradePosition(PositionData);
SCString Buffer; SCDateTime dt = sc.BaseDateTimeIn[sc.Index]; int CurrentBarDate =
dt.GetDate(); int CurrentBarTime = dt.GetTime();
int Year, Month, Day; dt.GetDateYMD(Year, Month, Day); int Hour, Minute, Second;
dt.GetTimeHMS(Hour, Minute, Second);
Buffer.Format("[%05d# %04d%02d%02d %02d:%02d] Ret=%d, Qty=%d, Price=%f, PL=%f",sc.Index+1,Year, Month, Day, Hour, Minute,
nRet,PositionData.PositionQuantity,PositionData.AveragePrice,PositionData.OpenProfitLoss);
sc.AddMessageToLog(Buffer,0);
Log: TrdEx1A.txt |
Example: RSISample.cpp:
View Trading errors etc: Trade/Trade Service Log
CrossOver/Uner
function
Reversals:
sc.MaximumPositionAllowed = 1; sc.SupportReversals = true;
sc.CancelAllOrdersOnEntriesAndReversals= true;
sc.AllowOppositeEntryWithOpposingPositionOrOrders = true;
sc.FreeDLL = 1; //on top always
MSFT 15 Min #1 | Trading CrossOver Example | BuyEntry signal is ignored because
maximum Long Position quantity allowed has been reached or would be exceeded with new order. Max. Position allowed: 1.
Resulting Position without existing orders: 100. Resulting Position with existing orders: 100
|
TickSize/Round
rounds to the nearest TickSize: newPrice =
sc.RoundToTickSize(newPrice);
float RoundToTickSize(float Value) + double RoundToTickSize(double Value)
double RoundToTickSize(double Value, double TickSize)
float TickSize;
|
Persistance/Permament:
Several persitent data elements are available - see
here
sc.Symbol, sc.StudyVersion, sc.StudyDescription sc.SymbolData,
sc.TickSize,,
sc.UserName
sc.SetPersistentInt(2, 40);
sc.SetPersistentFloat(1, 25.4f);
sc.SetPersistentFloat(2, 1.0f);
sc.GetPersistentInt(0) = 0;
sc.GetPersistentInt(1) = 0;
sc.GetPersistentInt(2) = 0;
sc.GetPersistentInt(3) = 0;
struct s_PersistentVariables
{
int i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12, i13, i14, i15, i16;
float f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16;
double d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11, d12, d13, d14, d15, d16,d17,d18,d19,d20,d21,d22,d23,d24,d25,d26,d27,d28,d29,d30,d31,d32;
SCDateTime scdt1,scdt2,scdt3,scdt4,scdt5,scdt6,scdt7,scdt8;
int Integers[64];
double Doubles[64];
void Clear () { memset(this, 0, sizeof(s_PersistentVariables)); }
};
|
Two Studies sharing Trade29
sc.GetStudyArrayFromChart()
similar to sc.GetStudyArray()
The second method involves using persistant
varaibles. using sc.GetStudyPersistentVariablesFromChartUsingID() |
|
|
|
|
|
|
|
|
|
Installing Compiler:
The compiler is not installed.
Click "Install Compiler" - C:\SierraChart\CPPCompiler
GCC http://prdownloads.sourceforge.net/mingw/gcc-c++-4.8.1-4-mingw32-dev.tar.lzma
C:\SierraChart\CPPCompiler>cd bin
C:\SierraChart\CPPCompiler\bin>mingw-get update
mingw-get: *** WARNING *** C:\SierraChart\CPPCompiler\var/lib/mingw-get/data/pro
file.xml: user configuration file missing
mingw-get: *** INFO *** C:\SierraChart\CPPCompiler\var/lib/mingw-get/data/defaul
ts.xml: trying system default configuration
Updating catalogue: package-list.xml; (item 1 of 1)
Updating catalogue: mingw32-package-list.xml; (item 2 of 3)
Updating catalogue: mingw32-autoconf.xml; (item 3 of 40)
Updating catalogue: mingw32-automake.xml; (item 4 of 40)
Updating catalogue: mingw32-basic-bsdtar.xml; (item 5 of 40)
|
|