NexusFi: Find Your Edge


Home Menu

 





Questions and discussion for Sierra Chart ACSIL for Beginners


Discussion in Sierra Chart

Updated
      Top Posters
    1. looks_one Trembling Hand with 43 posts (35 thanks)
    2. looks_two mosalem2003 with 39 posts (0 thanks)
    3. looks_3 1m1k3 with 20 posts (0 thanks)
    4. looks_4 bradhouser with 6 posts (9 thanks)
      Best Posters
    1. looks_one bobwest with 3.5 thanks per post
    2. looks_two bradhouser with 1.5 thanks per post
    3. looks_3 brach with 1 thanks per post
    4. looks_4 Trembling Hand with 0.8 thanks per post
    1. trending_up 27,694 views
    2. thumb_up 53 thanks given
    3. group 30 followers
    1. forum 118 posts
    2. attach_file 25 attachments




 
Search this Thread

Questions and discussion for Sierra Chart ACSIL for Beginners

  #81 (permalink)
mosalem2003
Toronto
 
Posts: 102 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

Reply With Quote

Can you help answer these questions
from other members on NexusFi?
Exit Strategy
NinjaTrader
ZombieSqueeze
Platforms and Indicators
Trade idea based off three indicators.
Traders Hideout
REcommedations for programming help
Sierra Chart
NT7 Indicator Script Troubleshooting - Camarilla Pivots
NinjaTrader
 
Best Threads (Most Thanked)
in the last 7 days on NexusFi
Spoo-nalysis ES e-mini futures S&P 500
29 thanks
Just another trading journal: PA, Wyckoff & Trends
25 thanks
Tao te Trade: way of the WLD
24 thanks
Bigger Wins or Fewer Losses?
23 thanks
GFIs1 1 DAX trade per day journal
17 thanks
  #82 (permalink)
 Trembling Hand 
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 View Post
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.

Follow me on Twitter Started this thread Reply With Quote
Thanked by:
  #83 (permalink)
mosalem2003
Toronto
 
Posts: 102 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 );

					}

Reply With Quote
  #84 (permalink)
mosalem2003
Toronto
 
Posts: 102 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;
		
			
    }

Reply With Quote
  #85 (permalink)
1m1k3
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!

Reply With Quote
  #86 (permalink)
 Trembling Hand 
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 View Post
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()

Follow me on Twitter Started this thread Reply With Quote
Thanked by:
  #87 (permalink)
1m1k3
Budapest, Hungary
 
Posts: 21 since Dec 2022
Thanks Given: 4
Thanks Received: 0


Trembling Hand View Post
In the docs it shows a method you need.
sc.GetLowest()

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()

Oh my... @Trembling Hand 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!

Reply With Quote
  #88 (permalink)
1m1k3
Budapest, Hungary
 
Posts: 21 since Dec 2022
Thanks Given: 4
Thanks Received: 0


1m1k3 View Post
Oh my... @Trembling Hand 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

Reply With Quote
  #89 (permalink)
1m1k3
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;
}

Reply With Quote
  #90 (permalink)
 Trembling Hand 
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 View Post
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.

Attached Thumbnails
Click image for larger version

Name:	2023-01-08 13_40_14-Sierra Chart 2443 forum_exampleChartbook1  SC Data - All Services 2023-01-08.png
Views:	51
Size:	139.9 KB
ID:	329013  
Follow me on Twitter Started this thread Reply With Quote




Last Updated on February 5, 2024


© 2024 NexusFi™, s.a., All Rights Reserved.
Av Ricardo J. Alfaro, Century Tower, Panama City, Panama, Ph: +507 833-9432 (Panama and Intl), +1 888-312-3001 (USA and Canada)
All information is for educational use only and is not investment advice. There is a substantial risk of loss in trading commodity futures, stocks, options and foreign exchange products. Past performance is not indicative of future results.
About Us - Contact Us - Site Rules, Acceptable Use, and Terms and Conditions - Privacy Policy - Downloads - Top
no new posts