Dark Theme
Light Theme
Trading Articles
Article Categories
Article Tools
Welcome to NexusFi: the best trading community on the planet, with over 150,000 members Sign Up Now for Free
Genuine reviews from real traders, not fake reviews from stealth vendors
Quality education from leading professional traders
We are a friendly, helpful, and positive community
We do not tolerate rude behavior, trolling, or vendors advertising in posts
We are here to help, just let us know what you need
You'll need to
register in order to view the content of the threads and start contributing to our community.
It's free for basic access, or support us by becoming an Elite Member -- see if you qualify for a discount below.
-- Big Mike, Site Administrator
(If you already have an account, login at the top of the page)
December 16th, 2020, 04:08 PM
Northern California where the girls are warm
Posts: 125 since Nov 2010
Thanks Given: 16
Thanks Received: 72
Code
if ( Input_StartTime.GetTime() <= CurrentBarTime <= Input_EndTime.GetTime() )
This won't work because you are trying to compare three numbers. Comparison operators only take two operands. You are really doing two comparisons, and they must both be true.
Can you help answer these questions from other members on NexusFi?
Best Threads (Most Thanked) in the last 7 days on NexusFi
December 16th, 2020, 09:42 PM
Melbourne, Land of Oz
Experience: Advanced
Platform: Sierra Chart, CQG
Broker: CQG
Trading: HSI
Posts: 246 since Jun 2011
Thanks Given: 28
Thanks Received: 360
A lot can be learnt about SC coding & C++ by just looking at the .cpp files in C:\SierraChart \ACS_Source
December 17th, 2020, 12:41 AM
Austin, TX
Experience: Intermediate
Platform: NT, SC, MT
Trading: NQ, ES, Micros
Posts: 89 since May 2018
Thanks Given: 188
Thanks Received: 269
mosalem2003
Code
if ( Input_StartTime.GetTime() <= CurrentBarTime <= Input_EndTime.GetTime() )
Syntax like that works as intended in some languages (such as Python).
In C++ it'll probably compile (assuming a time has a numeric representation) but it won't act as intended. The result will be
Code
if ( (Input_StartTime.GetTime() <= CurrentBarTime) <= Input_EndTime.GetTime() )
The first comparison will evaluate to true or false, which will convert to 0 or 1, which will likely always be smaller than the numeric representation of Input_EndTime.GetTime(). So overall the expression will always be true.
December 21st, 2020, 06:48 PM
Toronto
Posts: 103 since Apr 2019
Thanks Given: 106
Thanks Received: 23
Code
SCFloatArray DC_High;
sc.GetStudyArrayUsingID(Input_Subgraph_DC_High.GetStudyID(), Input_Subgraph_DC_High.GetSubgraphIndex(), DC_High);
SCFloatArray DC_Low;
sc.GetStudyArrayUsingID(Input_Subgraph_DC_Low.GetStudyID(), Input_Subgraph_DC_Low.GetSubgraphIndex(), DC_Low);
SCFloatArray DemandIndex;
sc.GetStudyArrayUsingID(Input_Subgraph_DemandIndex.GetStudyID(), Input_Subgraph_DemandIndex.GetSubgraphIndex(), DemandIndex);
SCFloatArray L2_Buyer;
SCFloatArray DI_Buyer;
if ( sc.Close[sc.Index-1] > DC_Low[sc.Index-1] && sc.Close[sc.Index-2] <= DC_Low[sc.Index-2] )
{
L2_Buyer [sc.Index-1] = sc.Close[sc.Index-1];
DI_Buyer [sc.Index-1] = DemandIndex[sc.Index-1];
LogString.Format (" check 1 " );
sc.AddMessageToLog(LogString, 0);
}
else
{
L2_Buyer [sc.Index-1] = L2_Buyer[sc.Index-2];
DI_Buyer [sc.Index-1] = DI_Buyer[sc.Index-2];
}
I am importing the Donchian Channel High, Low and the DemandIndex into arrays and starting filling other arrays L2_Buyer and DI_Buyer when the last bar closed above the Demand Index Low and the the previous bar closed below it ... Like the situation of Crossfrombelow.
When this condition happens, I need a new input to the L2_Buyer and DI_Buyer arrays and if not then there is no change from the last value in these arrays...
It seems not working as I am trying to print to message log and display that L2_Buyer but it has no change ? Any Idea ?
I
December 21st, 2020, 07:27 PM
Melbourne, Land of Oz
Experience: Advanced
Platform: Sierra Chart, CQG
Broker: CQG
Trading: HSI
Posts: 246 since Jun 2011
Thanks Given: 28
Thanks Received: 360
Should post all the code to make sure the inputs are indexed correctly and that logString is actually declared for example. Its much easier to reproduce and check rather than someone having to re-code everything to get a working example.
Also if you are printing to the log you might as well print the variable values that trigger it for a sanity check.
December 21st, 2020, 08:09 PM
Toronto
Posts: 103 since Apr 2019
Thanks Given: 106
Thanks Received: 23
As per your request, the full example code, and thanks in advance for all your support.
Code
SCSFExport scsf_msalem_Accumulation(SCStudyInterfaceRef sc)
{
//Inputs
///Imported studies subgraph(s) input arrays
SCInputRef Input_Subgraph_DC_High = sc.Input[0];
SCInputRef Input_Subgraph_DC_Low = sc.Input[1];
SCInputRef Input_Subgraph_DemandIndex = sc.Input[2];
//General system inputs
SCInputRef Input_Enabled = sc.Input[3];
SCInputRef Input_StartTime = sc.Input[4];
SCInputRef Input_EndTime = sc.Input[5];
//SCInputRef Input_FreeRange = sc.Input[5];
SCInputRef Input_MaxPosition = sc.Input[6];
SCInputRef Input_AttachedTradeWindowOrders = sc.Input[7];
//Trading Targets, Stops
SCInputRef Input_Target1_margin = sc.Input[8];
SCInputRef Input_Target2_margin= sc.Input[9];
SCInputRef Input_Target3_margin= sc.Input[10];
SCInputRef Input_Stopoffset = sc.Input[11];
//Subgraphs
//Trading Subgraphs
SCSubgraphRef Subgraph_BuyEntry = sc.Subgraph[0];
SCSubgraphRef Subgraph_SellEntry = sc.Subgraph[1];
SCSubgraphRef Subgraph_BuyExit = sc.Subgraph[2];
SCSubgraphRef Subgraph_SellExit = sc.Subgraph[3];
SCSubgraphRef Subgraph_DC_High = sc.Subgraph[4];
// Set configuration variables
if (sc.SetDefaults)
{
//Generic system defaults
sc.GraphName = "MSalem Institutional Accumulation Trading Algo";
sc.StudyDescription = "MSalem Institutional Accumulation Trading System";
sc.GraphRegion = 0;
sc.AutoLoop = 1;
sc.CalculationPrecedence = VERY_LOW_PREC_LEVEL;
//Inputs' Arrays defaults
//*SET/IMPORT* studies' subgraph(s)from the current chart: defaults to study 0, subgraph 0: change from the study settings to select the studies/subgraphs
Input_Subgraph_DC_High.Name = "DC: High";
Input_Subgraph_DC_High.SetStudySubgraphValues(1, 0);
Input_Subgraph_DC_Low.Name = "DC: Low";
Input_Subgraph_DC_Low.SetStudySubgraphValues(1, 1);
Input_Subgraph_DemandIndex.Name = "DemandIndex";
Input_Subgraph_DemandIndex.SetStudySubgraphValues(2,0);
//General system input defaults
Input_Enabled.Name = "Enabled";
Input_Enabled.SetYesNo(1);
Input_StartTime.Name = "Start Time";
Input_StartTime.SetTime(0);
Input_EndTime.Name = "End Time";
Input_EndTime.SetTime(SECONDS_PER_DAY - 1);
Input_MaxPosition.Name = "Max Position Allowed";
Input_MaxPosition.SetInt(10);
Input_AttachedTradeWindowOrders.Name = "Trade Window Orders";
Input_AttachedTradeWindowOrders.SetYesNo(false);
////Defaults for targets/stops
Input_Target1_margin.Name = "Target1 offset";
Input_Target1_margin.SetInt(20);
Input_Target2_margin.Name = "Target2 offset";
Input_Target2_margin.SetInt(10);
Input_Target3_margin.Name = "Target3 offset";
Input_Target3_margin.SetInt(5);
Input_Stopoffset.Name = "Stop offset";
Input_Stopoffset.SetInt(50);
//Subgraphs' arrays defaults
Subgraph_BuyEntry.Name = "Buy Entry";
Subgraph_BuyEntry.DrawStyle = DRAWSTYLE_ARROW_UP;
Subgraph_BuyEntry.PrimaryColor = RGB(0, 255, 0);
Subgraph_BuyEntry.LineWidth = 2;
Subgraph_BuyEntry.DrawZeros = false;
Subgraph_SellEntry.Name = "Sell Entry";
Subgraph_SellEntry.DrawStyle = DRAWSTYLE_ARROW_DOWN;
Subgraph_SellEntry.PrimaryColor = RGB(255, 0, 0);
Subgraph_SellEntry.LineWidth = 2;
Subgraph_SellEntry.DrawZeros = false;
Subgraph_BuyExit.Name = "Buy Exit";
Subgraph_BuyExit.DrawStyle = DRAWSTYLE_ARROW_DOWN;
Subgraph_BuyExit.PrimaryColor = RGB(255, 128, 128);
Subgraph_BuyExit.LineWidth = 2;
Subgraph_BuyExit.DrawZeros = false;
Subgraph_SellExit.Name = "Sell Exit";
Subgraph_SellExit.DrawStyle = DRAWSTYLE_ARROW_UP;
Subgraph_SellExit.PrimaryColor = RGB(128, 255, 128);
Subgraph_SellExit.LineWidth = 2;
Subgraph_SellExit.DrawZeros = false;
Subgraph_DC_High. Name = "DC_High";
Subgraph_DC_High.DrawStyle = DRAWSTYLE_LINE;
Subgraph_DC_High.PrimaryColor = RGB (128, 255, 128);
Subgraph_DC_High.LineWidth =2;
Subgraph_DC_High.DrawZeros = true;
//Trading variables defaults: can switch to system input.
// Only 1 trade for each Order Action type is allowed per bar.
sc.AllowOnlyOneTradePerBar = true;
sc.AllowEntryWithWorkingOrders = true;
sc.AllowMultipleEntriesInSameDirection = true;
//sc.CancelAllOrdersOnEntriesAndReversals = false;
sc.AllowOppositeEntryWithOpposingPositionOrOrders = true;
sc.SupportReversals = true;
sc.CancelAllOrdersOnReversals = true;
//sc.MaximumPositionAllowed = Input_MaxPosition.GetInt();
// This is false by default. Orders will go to the simulation system always.
sc.SendOrdersToTradeService = false;
sc.SupportAttachedOrdersForTrading = true;
//sc.UseGUIAttachedOrderSetting = true;
// This line can be within sc.SetDefaults or outside of it.
//sc.TradeWindowConfigFileName = "Test_2.twconfig";
sc.CancelAllWorkingOrdersOnExit = true;
//This needs to be set to true when a trading study uses trading functions.
sc.MaintainTradeStatisticsAndTradesData = true;
return;
}
// SYSTEM DATA Processing
//Setup for data processing
// **Get/IMPORT the array of the set studies(s) and corresponding subgraphs**
SCFloatArray DC_High;
sc.GetStudyArrayUsingID(Input_Subgraph_DC_High.GetStudyID(), Input_Subgraph_DC_High.GetSubgraphIndex(), DC_High);
SCFloatArray DC_Low;
sc.GetStudyArrayUsingID(Input_Subgraph_DC_Low.GetStudyID(), Input_Subgraph_DC_Low.GetSubgraphIndex(), DC_Low);
SCFloatArray DemandIndex;
sc.GetStudyArrayUsingID(Input_Subgraph_DemandIndex.GetStudyID(), Input_Subgraph_DemandIndex.GetSubgraphIndex(), DemandIndex);
// Get/IMPORT Inputs of selected studies ---Ex: the end Time for H/L study
// int EndTimeInput;
// sc.GetChartStudyInputInt(sc.ChartNumber, Input_Subgraph_HighofDay.GetStudyID(), 1, EndTimeInput);
// Get the time of the bar at the current index
int CurrentBarTime = sc.BaseDateTimeIn[sc.Index].GetTimeInSeconds();
sc.MaximumPositionAllowed = Input_MaxPosition.GetInt();
//bool TradingAllowed = Input_StartTime.GetTime() <= CurrentBarTime <= Input_EndTime.GetTime();
// last close price array
SCFloatArrayRef Last = sc.Close;
//structure to hold all position data
s_SCPositionData PositionData;
sc.GetTradePosition(PositionData);
// declare string to print log messages
SCString SignalString;
SCString LogString;
//// Use persistent variables to remember attached order IDs so they can be modified or canceled.
int32_t& Target1OrderID = sc.GetPersistentInt(1);
int32_t& Stop1OrderID = sc.GetPersistentInt(2);
// Process once per bar
int& LastBarIndexProcessed = sc.GetPersistentInt(11);
if (sc.Index == 0)
LastBarIndexProcessed = -1;
if (sc.Index == LastBarIndexProcessed)
return;
LastBarIndexProcessed = sc.Index;
//
///***************
if (!Input_Enabled.GetYesNo())
return;
if (sc.IsFullRecalculation)
return;
// Create an s_SCNewOrder object.
SCFloatArray L2_Buyer;
SCFloatArray L2_Seller;
SCFloatArray DI_Buyer;
SCFloatArray DI_Seller;
if ( sc.Close[sc.Index-1] > DC_Low[sc.Index-1] && sc.Close[sc.Index-2] <= DC_Low[sc.Index-2] )
//if ( sc.CrossOver(sc.Close, DC_Low) == CROSS_FROM_BOTTOM && sc.GetBarHasClosedStatus() == BHCS_BAR_HAS_CLOSED)
{
L2_Buyer [sc.Index-1] = sc.Close[sc.Index-1];
DI_Buyer [sc.Index-1] = DemandIndex[sc.Index-1];
LogString.Format (" check 1 " );
sc.AddMessageToLog(LogString, 0);
}
else
{
L2_Buyer [sc.Index-1] = L2_Buyer[sc.Index-2];
DI_Buyer [sc.Index-1] = DI_Buyer[sc.Index-2];
}
if ( sc.Close[sc.Index-1] < DC_High [sc.Index-1], sc.Close[sc.Index-2] >= DC_High[sc.Index-2])
{
L2_Seller[sc.Index-1] = sc.Close[sc.Index-1];
DI_Seller[sc.Index-1] = DemandIndex[sc.Index-1];
}
else
{
L2_Seller[sc.Index-1] = L2_Seller[sc.Index-2];
DI_Seller[sc.Index-1] = DI_Seller[sc.Index-2];
}
s_SCNewOrder NewOrder;
NewOrder.OrderQuantity = 1;
NewOrder.OrderType = SCT_ORDERTYPE_STOP_LIMIT;;
NewOrder.TimeInForce = SCT_TIF_GOOD_TILL_CANCELED;
/// Trading Logic
if ( Input_StartTime.GetTime() < CurrentBarTime && Input_EndTime.GetTime() > CurrentBarTime)
{
//////BUY ENTIRES *************
// If closed above the level high and no orders and no position, enter 3 limit buy orders at level high, mid-range, level low
// if ( sc.FormattedEvaluate(sc.Close[sc.Index], sc.BaseGraphValueFormat, GREATER_OPERATOR, Input_Subgraph_HighofDay[sc.Index], sc.BaseGraphValueFormat) &&
//sc.GetBarHasClosedStatus() == BHCS_BAR_HAS_CLOSED && PositionData.PositionQuantityWithAllWorkingOrders == 0 && PositionData.PositionQuantity <=0)
if ( L2_Buyer[sc.Index-1] != L2_Buyer[sc.Index-2] &&
L2_Buyer[sc.Index-1] < L2_Buyer[sc.Index-2] &&
DI_Buyer[sc.Index-1] > DI_Buyer[sc.Index-2]
)
{
//Buy Entry. Attached orders defined on Trade Window will be used.
//1st order
//define the Stop limit entry for order 1
NewOrder.Price1 = sc.High[sc.Index -1] + 1 * sc.TickSize;
//when not used the trade window attached orders then use the target stop attached orders margins from the level high otherwise use trade window attached orders
if (! Input_AttachedTradeWindowOrders.GetYesNo() )
{
NewOrder.Target1Offset = Input_Target1_margin.GetInt() * sc.TickSize;
NewOrder.Stop1Offset = Input_Stopoffset.GetInt() * sc.TickSize;
NewOrder.OCOGroup1Quantity = 1;
}
int Result = (int)sc.BuyEntry(NewOrder);
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 Stop Limit 1: %.2f & Buy Target1: %.2f & CurrentBarTime: %d & Max Position Allowed: %d", NewOrder.Price1, NewOrder.Price1+ NewOrder.Target1Offset, CurrentBarTime, Input_MaxPosition.GetInt());
sc.AddMessageToLog(SignalString, 0);
}
}
// SELL ENTRIES ******
// Sell when the last price crosses the moving average from above.
//else if (sc.CrossOver(sc.Close, Input_Subgraph_LowofDay) == CROSS_FROM_TOP && sc.GetBarHasClosedStatus() == BHCS_BAR_HAS_CLOSED)
//else if (sc.Close < Input_Subgraph_LowofDay[sc.Index] && sc.GetBarHasClosedStatus() == BHCS_BAR_HAS_CLOSED && PositionData.PositionQuantity == 0)
//else if ( sc.FormattedEvaluate(sc.Close[sc.Index], sc.BaseGraphValueFormat, LESS_OPERATOR, Input_Subgraph_LowofDay[sc.Index], sc.BaseGraphValueFormat) && sc.GetBarHasClosedStatus() == BHCS_BAR_HAS_CLOSED && PositionData.PositionQuantityWithAllWorkingOrders == 0 && PositionData.PositionQuantity >=0)
else if (
L2_Seller[sc.Index-1] != L2_Seller[sc.Index-2] &&
L2_Seller[sc.Index-1]> L2_Seller[sc.Index-2] &&
DI_Seller[sc.Index-1]< DI_Seller[sc.Index-2]
)
{
//Sell Entry. Attached orders defined on Trade Window will be used.
//1st order
NewOrder.Price1 = sc.Low[sc.Index-1] - 1 * sc.TickSize;
if (! Input_AttachedTradeWindowOrders.GetYesNo() )
{
NewOrder.Target1Offset = Input_Target1_margin.GetInt() * sc.TickSize;
NewOrder.Stop1Offset = Input_Stopoffset.GetInt() * sc.TickSize;
NewOrder.OCOGroup1Quantity = 1;
}
int Result = (int)sc.SellEntry(NewOrder);
if (Result > 0) //If there has been a successful order entry, then draw an arrow at the high of the bar.
{
Subgraph_SellEntry[sc.Index-1] = sc.High[sc.Index-1];
SignalString.Format("Sell Stop Limit 1: %.2f & Sell Target1: %.2f & CurrentBarTime: %d", NewOrder.Price1, NewOrder.Price1 - NewOrder.Target1Offset, CurrentBarTime);
sc.AddMessageToLog(SignalString, 0);
}
}
}
}
December 21st, 2020, 08:14 PM
Melbourne, Land of Oz
Experience: Advanced
Platform: Sierra Chart, CQG
Broker: CQG
Trading: HSI
Posts: 246 since Jun 2011
Thanks Given: 28
Thanks Received: 360
I would change these,
Code
SCFloatArray L2_Buyer;
SCFloatArray L2_Seller;
SCFloatArray DI_Buyer;
SCFloatArray DI_Seller;
to SCSubgraphRef and have the DrawStyle = DRAWSTYLE_IGNORE and see what values are being populated to the arrays. suspect they are getting reset every call to 0's but haven't time at the moment to check.
December 21st, 2020, 08:23 PM
Toronto
Posts: 103 since Apr 2019
Thanks Given: 106
Thanks Received: 23
Thanks a lot for the response. I will try your recommendation accordingly.
Sent using the NexusFi mobile app
December 21st, 2020, 08:42 PM
Toronto
Posts: 103 since Apr 2019
Thanks Given: 106
Thanks Received: 23
I did the suggested change but still the same performance of the code. I will stay tuned for your feedback whenever you have time.
December 21st, 2020, 09:41 PM
Melbourne, Land of Oz
Experience: Advanced
Platform: Sierra Chart, CQG
Broker: CQG
Trading: HSI
Posts: 246 since Jun 2011
Thanks Given: 28
Thanks Received: 360
You have a logic error. The default logic for the code sets the value to zero 1 bar ago as that value isn't populated on the start of the study calculation.
I think you are trying to store a close value in that through the L2_Buyer array?
Last Updated on April 23, 2024