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)
October 7th, 2022, 04:30 PM
Toronto
Posts: 103 since Apr 2019
Thanks Given: 106
Thanks Received: 23
Thanks a lot for your feedback and guidance. I am still at beginner level, so excuse my primitive challenges. I have pasted the code for your reference and I have used the imprecision float comparison. I am only challenged now with the change of the Inputs that are boolean to persistent int or float that can represent boolean.
On another note, how to make sure that whenever I replay that the chart will initialize -- for example, whenever I replay the chart with the trading system, it seems to do some calculation and set the variables to some values based may be on calculation on the visible bars ?
Kindly review and let me know wherever there is an opportunity to optimize in the below code -- Thanks a lot in advance for all of your support and again excuse me being a beginner and I just try my best to use code from examples to make a trading system examples ..
Code
//The top of every source code file must include this line
#include "sierrachart.h"
SCDLLName("DC_COB Algos test ")
SCSFExport scsf_msalem_DC_COB_V11_test(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_DC_Mid = sc.Input[16];
//General system inputs
SCInputRef Input_Enabled = sc.Input[3];
SCInputRef Input_StartTime = sc.Input[4];
SCInputRef Input_EndTime = 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];
///processing
SCInputRef L = sc.Input[12];
SCInputRef S = sc.Input[13];
SCInputRef x = sc.Input[14];
SCInputRef y = sc.Input[15];
SCInputRef RL = sc.Input[16];
SCInputRef RS = sc.Input[17];
//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];
//processing subgraphs
// Set configuration variables
if (sc.SetDefaults)
{
//Generic system defaults
sc.GraphName = "MSalem DC_COB Algo test ";
sc.StudyDescription = "MSalem DC_COB 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_DC_Mid.Name = "DC: Mid";
Input_Subgraph_DC_Mid.SetStudySubgraphValues(1, 2);
//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);
///processing input defaults - when no name then they will not appear in settings of the algo
L.SetYesNo(0);
S.SetYesNo(0);
RL.SetYesNo(0);
RS.SetYesNo(0);
x.SetYesNo(0);
y.SetYesNo(0);
///How to convert boolean to persistent variable as int or float, it doesn't compile?
//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;
// Processing Subgraphs' arrays defaults
//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 = Input_AttachedTradeWindowOrders.GetYesNo();
// This line can be within sc.SetDefaults or outside of it.
//sc.TradeWindowConfigFileName = "Test_2.twconfig";
sc.CancelAllWorkingOrdersOnExit = true;
sc.CancelAllOrdersOnEntriesAndReversals = false;
//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 DC_Mid;
sc.GetStudyArrayUsingID(Input_Subgraph_DC_Mid.GetStudyID(), Input_Subgraph_DC_Mid.GetSubgraphIndex(), DC_Mid);
// Get the time of the bar at the current index
int CurrentBarTime = sc.BaseDateTimeIn[sc.Index].GetTimeInSeconds();
sc.MaximumPositionAllowed = Input_MaxPosition.GetInt();
// 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);
int32_t& init_count = sc.GetPersistentInt(3);
float & DCHB = sc.GetPersistentFloat(1);
float & DCLB = sc.GetPersistentFloat(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.
s_SCNewOrder NewOrder;
NewOrder.OrderQuantity = 1;
NewOrder.OrderType = SCT_ORDERTYPE_STOP_LIMIT;;
NewOrder.TimeInForce = SCT_TIF_GOOD_TILL_CANCELED;
if (init_count==0)
{
LogString.Format("Initial Values & Long: %d & Short: %d & RLong: %d & RShort: %d & DCLB: %f & DCHB: %f & init_count %d ", L.GetYesNo(), S.GetYesNo(), RL.GetYesNo(), RS.GetYesNo(),DCLB, DCHB, init_count);
sc.AddMessageToLog (LogString, 0);
}
///this code always starts with RL = 1 how come ?
///////////////////////////////////////////////////////////// Main DATA PROCESSING to decide Long or Short ///////////////////////////
//close above DC high
// if ( sc.Close[sc.Index - 1] > DC_High[sc.Index - 2] && sc.Close[sc.Index - 2] <= DC_High[sc.Index - 3] && S.GetYesNo() && !L.GetYesNo() )
if ( sc.FormattedEvaluate(sc.Close[sc.Index - 1], sc.BaseGraphValueFormat, GREATER_OPERATOR, DC_High[sc.Index - 2], sc.BaseGraphValueFormat)==1 &&
sc.FormattedEvaluate(sc.Close[sc.Index - 2], sc.BaseGraphValueFormat, LESS_EQUAL_OPERATOR, DC_High[sc.Index - 3], sc.BaseGraphValueFormat)==1
// && ( S.GetYesNo() || RS.GetYesNo() || L_S_t0.GetYesNo() ) && !L.GetYesNo() )
&& ( S.GetYesNo() || RS.GetYesNo() || (init_count<2) ) && !L.GetYesNo() )
//if ( sc.CrossOver(Last, DC_High) == CROSS_FROM_BOTTOM && sc.GetBarHasClosedStatus() == BHCS_BAR_HAS_CLOSED && S.GetYesNo() && !L.GetYesNo())
{
DCHB = DC_High[sc.Index - 2];
L.SetYesNo(1);
RS.SetYesNo(0);
RL.SetYesNo(0);
x.SetYesNo(1);
S.SetYesNo(0);
if (init_count<2){init_count++;}
sc.FlattenAndCancelAllOrders();
LogString.Format("Initial Long with DC High Break & Long: %d & Short: %d & RLong: %d & RShort: %d & DCLB: %f & DCHB: %f & init_count %d ", L.GetYesNo(), S.GetYesNo(), RL.GetYesNo(), RS.GetYesNo(),DCLB, DCHB, init_count);
sc.AddMessageToLog (LogString, 0);
}
//if ( L.GetYesNo() && sc.Close[sc.Index-1] < DCHB && x.GetYesNo() )
//if (L.GetYesNo() && sc.FormattedEvaluate(sc.Close[sc.Index - 1], sc.BaseGraphValueFormat, LESS_OPERATOR, DCHB, sc.BaseGraphValueFormat)==1 && x.GetYesNo() && !L_S_t0.GetYesNo())
if (L.GetYesNo() && sc.FormattedEvaluate(sc.Close[sc.Index - 1], sc.BaseGraphValueFormat, LESS_OPERATOR, DCHB, sc.BaseGraphValueFormat)==1 && x.GetYesNo() && (init_count==2))
{
RS.SetYesNo(1);
RL.SetYesNo(0);
L.SetYesNo(0);
S.SetYesNo(0);
x.SetYesNo(0);
DCLB = DC_High[sc.Index - 1]; //avoid switching long unless u break the DC channel as it should be new short initialization not compare to the negated potential long break, then DCLB assigned to high DC
sc.FlattenAndCancelAllOrders();
LogString.Format("Return back Inside Short Value & Long: %d & Short: %d & RLong: %d & RShort: %d & DCLB: %f & DCHB: %f & init_count %d ", L.GetYesNo(), S.GetYesNo(), RL.GetYesNo(), RS.GetYesNo(),DCLB, DCHB, init_count);
sc.AddMessageToLog (LogString, 0);
}
//Close below DC low
//if ( sc.Close[sc.Index - 1] < DC_Low[sc.Index - 2] && sc.Close[sc.Index - 2] >= DC_Low[sc.Index - 3] && L.GetYesNo() && !S.GetYesNo() )
if ( sc.FormattedEvaluate(sc.Close[sc.Index - 1], sc.BaseGraphValueFormat, LESS_OPERATOR, DC_Low[sc.Index - 2], sc.BaseGraphValueFormat)==1 &&
sc.FormattedEvaluate(sc.Close[sc.Index - 2], sc.BaseGraphValueFormat, GREATER_EQUAL_OPERATOR, DC_Low[sc.Index - 3], sc.BaseGraphValueFormat)==1
// && ( L.GetYesNo()|| RL.GetYesNo() || L_S_t0.GetYesNo()) && !S.GetYesNo() )
&& ( L.GetYesNo()|| RL.GetYesNo() || (init_count<2)) && !S.GetYesNo() )
//if ( sc.CrossOver(Last, DC_Low) == CROSS_FROM_TOP && sc.GetBarHasClosedStatus() == BHCS_BAR_HAS_CLOSED && L.GetYesNo() && !S.GetYesNo() )
{
DCLB = DC_Low[sc.Index - 2];
S.SetYesNo(1);
L.SetYesNo(0);
RS.SetYesNo(0);
RL.SetYesNo(0);
y.SetYesNo(1);
if (init_count<2){init_count++;}
sc.FlattenAndCancelAllOrders();
LogString.Format("Initial Short with DC Low break & Long: %d & Short: %d & RLong: %d & RShort: %d & DCLB: %f & DCHB: %f & init_count: %d ", L.GetYesNo(), S.GetYesNo(), RL.GetYesNo(), RS.GetYesNo(),DCLB, DCHB, init_count);
sc.AddMessageToLog (LogString, 0);
}
//if (S.GetYesNo() && sc.Close[sc.Index-1] > DCLB && y.GetYesNo() )
//if (S.GetYesNo() && sc.FormattedEvaluate(sc.Close[sc.Index - 1], sc.BaseGraphValueFormat, GREATER_OPERATOR, DCLB, sc.BaseGraphValueFormat)==1 && y.GetYesNo() && !L_S_t0.GetYesNo())
if (S.GetYesNo() && sc.FormattedEvaluate(sc.Close[sc.Index - 1], sc.BaseGraphValueFormat, GREATER_OPERATOR, DCLB, sc.BaseGraphValueFormat)==1 && y.GetYesNo() && (init_count==2))
{
RL.SetYesNo(1);
RS.SetYesNo(0);
S.SetYesNo(0);
L.SetYesNo(0);
y.SetYesNo(0);
DCHB = DC_Low[sc.Index - 1]; //avoid switching short unless u break the low of the DC channel as it should be new long initialization not compare to the negated potential short break, then DCHB assigned to low DC
sc.FlattenAndCancelAllOrders();
LogString.Format("Return back inside Long Value & Long: %d & Short: %d & RLong: %d & RShort: %d & DCLB: %f & DCHB: %f & init_count: %d &", L.GetYesNo(), S.GetYesNo(), RL.GetYesNo(), RS.GetYesNo(),DCLB, DCHB, init_count);
sc.AddMessageToLog (LogString, 0);
}
/// Trading Logic for order entry and management
if (Input_StartTime.GetTime() < CurrentBarTime && Input_EndTime.GetTime() > CurrentBarTime)
{
//////BUY ENTIRES *************
if (
(L.GetYesNo() || RL.GetYesNo()) && sc.Close[sc.Index-1] < sc.Open[sc.Index-1] && PositionData.PositionQuantity < sc.MaximumPositionAllowed && init_count >0
)
{
//Cancel all orders except pending attached orders
// This is an example of iterating the order list in Sierra Chart for orders
// matching the Symbol and Trade Account of the chart, and finding the orders
// that have a Status of Open and are not Attached Orders.
int Index = 0;
s_SCTradeOrder OrderDetails;
while( sc.GetOrderByIndex (Index, OrderDetails) != SCTRADING_ORDER_ERROR)
{
Index++; // Increment the index for the next call to sc.GetOrderByIndex
if (OrderDetails.OrderStatusCode != SCT_OSC_OPEN)
continue;
if (OrderDetails.ParentInternalOrderID != 0)//This means this is an Attached Order
continue;
//Get the internal order ID
int InternalOrderID = OrderDetails.InternalOrderID;
int Result_cancel = sc.CancelOrder(InternalOrderID );
}
//Buy Entry. Attached orders defined on Trade Window will be used when Input_AttachedTradeWindowOrders = true
//1st order
//define the Stop limit entry for order 1
//SignalString.Format("long condition works & Long: %f & Short: %f & Potential_Long: %f & Potential_Short: %f", Long[sc.Index-1], Short[sc.Index-1], Potential_Long[sc.Index-1], Potential_Short[sc.Index-1]);
//sc.AddMessageToLog (SignalString, 0);
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.Stop1Offset = sc.High[sc.Index-1] - sc.Low[sc.Index-1] + 2 * 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];
// Remember the order IDs for subsequent modification and cancellation
Target1OrderID = NewOrder.Target1InternalOrderID;
Stop1OrderID = NewOrder.Stop1InternalOrderID;
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 ******
else if (
(S.GetYesNo() ||RS.GetYesNo()) && sc.Close[sc.Index-1] > sc.Open[sc.Index-1] && PositionData.PositionQuantity < sc.MaximumPositionAllowed && init_count>0
)
{
//Cancel all orders except pending attached orders
// This is an example of iterating the order list in Sierra Chart for orders
// matching the Symbol and Trade Account of the chart, and finding the orders
// that have a Status of Open and are not Attached Orders.
int Index = 0;
s_SCTradeOrder OrderDetails;
while( sc.GetOrderByIndex (Index, OrderDetails) != SCTRADING_ORDER_ERROR)
{
Index++; // Increment the index for the next call to sc.GetOrderByIndex
if (OrderDetails.OrderStatusCode != SCT_OSC_OPEN)
continue;
if (OrderDetails.ParentInternalOrderID != 0)//This means this is an Attached Order
continue;
//Get the internal order ID
int InternalOrderID = OrderDetails.InternalOrderID;
int Result_cancel = sc.CancelOrder(InternalOrderID );
}
//Sell Entry. Attached orders defined on Trade Window will be used when Input_AttachedTradeWindowOrders = true
//1st order
//SignalString.Format("short condition works & Long: %f & Short: %f & Potential_Long: %f & Potential_Short: %f", Long[sc.Index-1], Short[sc.Index-1], Potential_Long[sc.Index-1], Potential_Short[sc.Index-1]);
//sc.AddMessageToLog (SignalString, 0);
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.Stop1Offset = sc.High[sc.Index-1] - sc.Low[sc.Index-1] + 2 * 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];
// Remember the order IDs for subsequent modification and cancellation
Target1OrderID = NewOrder.Target1InternalOrderID;
Stop1OrderID = NewOrder.Stop1InternalOrderID;
SignalString.Format("Sell Stop Limit 1: %.2f & Sell Target1: %.2f & CurrentBarTime: %d", NewOrder.Price1, NewOrder.Price1 - NewOrder.Target1Offset, CurrentBarTime);
sc.AddMessageToLog(SignalString, 0);
}
}
//modify stop order
bool ExecuteModifyOrder = false;
if (ExecuteModifyOrder && (sc.Index == sc.ArraySize - 1) && PositionData.PositionQuantity != 0 &&
//&& PositionData.OpenProfitLoss >= 10 *sc.TickSize && (
( (L.GetYesNo() && (sc.Low[sc.Index-1] - sc.Low[sc.Index-2] > 5 * sc.TickSize) ) || (S.GetYesNo() && (sc.High[sc.Index-2]-sc.High[sc.Index-1] > 5 *sc.TickSize )) ) )//Only do a modify on the most recent bar
{
double NewStop = 0.0;
// Get the existing target order
s_SCTradeOrder ExistingOrder;
if (sc.GetOrderByOrderID(Stop1OrderID, ExistingOrder) != SCTRADING_ORDER_ERROR)
{
if (ExistingOrder.BuySell == BSE_BUY)
NewStop= sc.High[sc.Index -1] + 1 *sc.TickSize;
else if (ExistingOrder.BuySell == BSE_SELL )
NewStop = sc.Low[sc.Index -1] - 1 *sc.TickSize;
// We can only modify price and/or quantity
s_SCNewOrder ModifyOrder;
ModifyOrder.InternalOrderID = Stop1OrderID;
ModifyOrder.Price1 = NewStop;
sc.ModifyOrder(ModifyOrder);
}
}
}
}
/////////////////////////////////////// END of FILE ////////////// watch last curly closed bracket at the end
Can you help answer these questions from other members on NexusFi?
Best Threads (Most Thanked) in the last 7 days on NexusFi
October 8th, 2022, 03:02 AM
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
mosalem2003
Thanks a lot for your feedback and guidance. I am still at beginner level, so excuse my primitive challenges. I have pasted the code for your reference and I have used the imprecision float comparison. I am only challenged now with the change of the Inputs that are boolean to persistent int or float that can represent boolean.
On another note, how to make sure that whenever I replay that the chart will initialize -- for example, whenever I replay the chart with the trading system, it seems to do some calculation and set the variables to some values based may be on calculation on the visible bars ?
Kindly review and let me know wherever there is an opportunity to optimize in the below code -- Thanks a lot in advance for all of your support and again excuse me being a beginner and I just try my best to use code from examples to make a trading system examples ..
No too sure what your second point is but the problems probably come from not setting your Bool variables correctly on initialization. This start up block should fix that.
You really should change those SCInputRef to PersistentInt like this,
Code
int& Target1OrderID = sc.GetPersistentInt(1);
int& Stop1OrderID = sc.GetPersistentInt(2);
int& init_count = sc.GetPersistentInt(3);
int& LastBarIndexProcessed = sc.GetPersistentInt(4);
int& L = sc.GetPersistentInt(5);
int& S = sc.GetPersistentInt(6);
int& RL = sc.GetPersistentInt(7);
int& RS = sc.GetPersistentInt(8);
int& x = sc.GetPersistentInt(9);
int& y = sc.GetPersistentInt(10);
// Process once per bar
if (sc.Index == 0)
{
// on first Bar set all Persistent varribles to the starting state
LastBarIndexProcessed = -1;
L = 0;
S = 0;
RL = 0;
RS = 0;
x = 0;
y = 0;
}
if (sc.Index == LastBarIndexProcessed)
return;
LastBarIndexProcessed = sc.Index;
So they are all now false = 0. When you want them to be true set them to 1. Then in each "if" block you check for,
Code
// This
if (RL == 1) // True or RL == 0 for false
{
// Do something
}
// Rather than this
if ( L.GetYesNo() )
{
// Do something
}
Its also good coding to name your variables so someone can read them and understand what they do so something like
Code
// This
int& LastLow = sc.GetPersistentInt(5);
// Rather than this
int& L= sc.GetPersistentInt(5);
You also need to fix your order logic. Its way too complicated and repeats iterating every cycle multiple s_SCTradeOrder OrderDetails loops. You only have to do that once. Its one of the more computational heavy tasks in SC, especially if you have lots of trades attached in testing.
October 11th, 2022, 01:30 AM
Toronto
Posts: 103 since Apr 2019
Thanks Given: 106
Thanks Received: 23
Thanks a lot for your helpful feedback and support as usual.
I have updated the code to use persistent variables rather than inputs.
It was not working when variables are reset at the last bar for some reason. However, I removed the reset state from this code and it works as the original one.
Code
// Process once per bar
if (sc.Index == 0)
{
LastBarIndexProcessed = -1;
}
if (sc.Index == LastBarIndexProcessed)
return;
LastBarIndexProcessed = sc.Index;
It seems this code is for limiting one time processing in real time for the last bar. I assume the code try to set LastBarIndexProcessed = -1; but needs to clarify how this code limits more than one time processing while last bar is forming in real time. When the persistent variables was reset at the sc.Index ==0, the code didn't work, so I removed it as above and then it starts to work assuming that the persistent variables are reset at the start by default.
On your other recommendation for the ordering logic for the following code, it only executes when there is an buy entry or sell entry condition, and the code below for the buy entry condition - it should iterates all orders and cancel all open orders that are not filled except open attached orders -- How can we achieve this goal without impact the performance as you noted. I assumed it was not only executing at the if condition and not working all the time ..
Code
if ((L == 1 || RL == 1) && sc.Close[sc.Index-1] < sc.Open[sc.Index-1] && PositionData.PositionQuantity < sc.MaximumPositionAllowed && init_count >0)
{
//Cancel all orders except pending attached orders
// This is an example of iterating the order list in Sierra Chart for orders
// matching the Symbol and Trade Account of the chart, and finding the orders
// that have a Status of Open and are not Attached Orders.
int Index = 0;
s_SCTradeOrder OrderDetails;
while( sc.GetOrderByIndex (Index, OrderDetails) != SCTRADING_ORDER_ERROR)
{
Index++; // Increment the index for the next call to sc.GetOrderByIndex
if (OrderDetails.OrderStatusCode != SCT_OSC_OPEN)
continue;
if (OrderDetails.ParentInternalOrderID != 0)//This means this is an Attached Order
continue;
//Get the internal order ID
int InternalOrderID = OrderDetails.InternalOrderID;
int Result_cancel = sc.CancelOrder(InternalOrderID );
}
October 13th, 2022, 02:58 AM
Toronto
Posts: 103 since Apr 2019
Thanks Given: 106
Thanks Received: 23
<< I have fixed this part regarding the resets using ur initial proposal as follows and now the persistent variables resets properly, I noticed the issue was a syntax in the assignments in the code body not at this reset statement , for example I was using L==1 within the if statement and the compiler was successful !!, when I change it to L=1 then it works , the compiler should have generated an error >>
Code
if (sc.Index == 0)
{
LastBarIndexProcessed = -1;
L = 0;
S = 0;
RL = 0;
RS = 0;
}
December 3rd, 2022, 08:57 AM
Budapest, Hungary
Posts: 21 since Dec 2022
Thanks Given: 4
Thanks Received: 0
Hi everyone,
I'm quite new at ASCIL therefore I've got some questions.
First of all how can I check something has happened in a certain bar period?
To be more specific I'd like to get the result for that, for example the RSI has been under 30 between [sc.Index -30] and [sc.Index - 10]?
In spreadsheet it was easy I just used the EARLIESTNONZEROVALUE(L12:L32). 'L' the column where results are stored for RSI<30.
But in ASCIL so far I olny know the get.Lowest function for this which evaluate the last 'n' bars till [sc.Index].
Thanks!
December 4th, 2022, 04:06 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
1m1k3
Hi everyone,
I'm quite new at ASCIL therefore I've got some questions.
First of all how can I check something has happened in a certain bar period?
To be more specific I'd like to get the result for that, for example the RSI has been under 30 between [sc.Index -30] and [sc.Index - 10]?
In spreadsheet it was easy I just used the EARLIESTNONZEROVALUE(L12:L32). 'L' the column where results are stored for RSI<30.
But in ASCIL so far I olny know the get.Lowest function for this which evaluate the last 'n' bars till [sc.Index].
Thanks!
In the docs it shows a method you need.
sc.GetLowest()
https://www.sierrachart.com/index.php?page=doc/ACSIL_Members_Functions.html
Quoting
float GetLowest(SCFloatArrayRef FloatArrayIn, int Index, int Length);
You want the lowest value (FloatArrayIn = sc.Low) starting 10 bars ago (Index = sc.Index-10) for 20 bars back (Length = 20)
This will return a single value if you want it into a Float array for charting use the same this function
sc.Lowest()
December 6th, 2022, 03:21 AM
Budapest, Hungary
Posts: 21 since Dec 2022
Thanks Given: 4
Thanks Received: 0
January 5th, 2023, 06:20 AM
Budapest, Hungary
Posts: 21 since Dec 2022
Thanks Given: 4
Thanks Received: 0
1m1k3
Oh my... you should've written the examples for the
Sierra Chart ASCIL functions
. Now it's so obvious
Many thanks!
Hopefully with time I will accustome to looking for different solutions what I used in spreadsheets.
Now i got another queation if you don't mind.
How can I mark an event and count the bars since then?
For example there is a crossover between two moving averages and I'd like to know how many bars before happend that for furter evaluate. Obviously this number incrases by time with every new bar.
Someting like the GetBarsSinceLastTradeOrderEntry() but I want to define the event of the start for counting.
Is there a function for it?
Thanks!
I found a solution for this in the Studies2.cpp
January 5th, 2023, 04:17 PM
Budapest, Hungary
Posts: 21 since Dec 2022
Thanks Given: 4
Thanks Received: 0
Hi everyone,
I have more charts in my chartbook and for a calculation I need subgraph value from another chart. Just to make it simple there are only 4 charts in the chartbook. I put the a study which suppose to this onto chart#4 .
If I set chart#4 in the Study Settings I get correct values. But if I set any other chart I get such kind of value what not even close to any of the subgraphs of any charts.
I tried both ways I found on Sierre Chart site: sc.GetStudyArrayFromChart() and sc.GetStudyArrayFromChartUsingID() and the result is same.
Can someone tell me what do I do wrong?
Here are the codes I used:
Code
{
SCSubgraphRef Subgraph_Signal = sc.Subgraph[0];
// logging object
SCString msg;
// inputs
SCInputRef StudySubgraph1 = sc.Input[0];
SCInputRef Value = sc.Input[3];
// Set configuration variables
if (sc.SetDefaults)
{
sc.GraphName = "My Study Reference";
sc.GraphRegion = 0;
Subgraph_Signal.Name = "Signal";
Subgraph_Signal.DrawStyle = DRAWSTYLE_BACKGROUND_TRANSPARENT;
Subgraph_Signal.PrimaryColor = RGB(0,255,0);
StudySubgraph1.Name = "Study Subgraph 1";
StudySubgraph1.SetChartStudySubgraphValues(3,1, 0);
Value.Name = "Signal Valuealue #";
Value.SetInt(50);
return;
}
// declare variable to hold the array of volumes
// from each of the studies
SCFloatArray RSI_Ref;
//pass these in by reference to populate these arrays with the study values
sc.GetStudyArrayFromChartUsingID(StudySubgraph1.GetChartStudySubgraphValues(), RSI_Ref);
// create a string that displays the current values
msg.Format("C1 RSI: %.1f", RSI_Ref[sc.Index]);
sc.AddMessageToLog(msg, 1);
if
(
(RSI_Ref[sc.Index] > Value.GetInt())
)
Subgraph_Signal[sc.Index] = 1;
else
Subgraph_Signal[sc.Index] = 0;
Code
{
SCSubgraphRef Subgraph_Signal = sc.Subgraph[0];
// logging object
SCString msg;
// inputs
SCInputRef Chart = sc.Input[0];
SCInputRef Study = sc.Input[1];
SCInputRef Subgraph = sc.Input[2];
SCInputRef Value = sc.Input[3];
// Set configuration variables
if (sc.SetDefaults)
{
sc.GraphName = "My Study Reference2";
sc.GraphRegion = 0;
Subgraph_Signal.Name = "Signal";
Subgraph_Signal.DrawStyle = DRAWSTYLE_BACKGROUND_TRANSPARENT;
Subgraph_Signal.PrimaryColor = RGB(0,255,0);
Chart.Name = "Chart #";
Chart.SetInt(3);
Study.Name = "Study #";
Study.SetInt(1);
Subgraph.Name = "Subgraph #";
Subgraph.SetInt(1);
Value.Name = "Signal Valuealue #";
Value.SetInt(50);
return;
}
// declare variable to hold the array of volumes
// from each of the studies
SCFloatArray RSI_Ref;
//pass these in by reference to populate these arrays with the study values
sc.GetStudyArrayFromChart(Chart.GetInt(), Study.GetInt(), Subgraph.GetInt(), RSI_Ref);
// create a string that displays the current values
msg.Format("C1 RSI: %.1f", RSI_Ref[sc.Index]);
sc.AddMessageToLog(msg, 1);
if
(
(RSI_Ref[sc.Index] > Value.GetInt())
)
Subgraph_Signal[sc.Index] = 1;
else
Subgraph_Signal[sc.Index] = 0;
}
January 7th, 2023, 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
1m1k3
If I set chart#4 in the Study Settings I get correct values. But if I set any other chart I get such kind of value what not even close to any of the subgraphs of any charts.
Works for me in replay and I assume live too. Not on historical loading as the calculations are independent on loading.
Last Updated on April 23, 2024