Support Board
Date/Time: Tue, 09 Sep 2025 18:52:53 +0000
[Programming Help] - LifeCycle of sc.SupportTradingScaleOut in a study?
View Count: 230
[2025-07-14 23:56:37] |
rajeshh - Posts: 25 |
Hello: I am trying to understand what it means to switch the values of sc.SupportTradingScaleOut in a study? Can it only be set once for a run of the study? I have a case where I want to be able to scaleOut during the lifetime of a bar except on the bar close, when I may place an opposite order with attached orders in my study. I have tried: sc.SupportTradingScaleIn = 1;
if (sc.GetBarHasClosedStatus() != BHCS_BAR_HAS_CLOSED) sc.SupportTradingScaleOut = 1; else { sc.SupportTradingScaleOut = 0; //Submit order to create an opposite order with attached orders does not create attached orders, only the opposite order. If I always have sc.SupportTradingScaleOut = 0; , then when the opposite order is created, it also has attached orders. But this means I cannot use the ScaleOut at all.
Date Time Of Last Edit: 2025-07-15 01:53:15
|
[2025-07-15 02:34:10] |
ForgivingComputers.com - Posts: 1114 |
I want to be able to scaleOut during the lifetime of a bar except on the bar close, when I may place an opposite order with attached orders in my study.
Change BHCS_BAR_HAS_CLOSED
to BHCS_BAR_HAS_NOT_CLOSED
sc.SupportTradingScaleIn = 1;
if (sc.GetBarHasClosedStatus() != BHCS_BAR_HAS_NOT_CLOSED) sc.SupportTradingScaleOut = 1; else sc.SupportTradingScaleOut = 0; //Submit order to create an opposite order with attached orders does not create attached orders, only the opposite order. |
[2025-07-15 04:20:58] |
rajeshh - Posts: 25 |
In which case != also changes to ==, correct?
|
[2025-07-15 10:18:04] |
rajeshh - Posts: 25 |
I have tried this, and still the same behavior - if (sc.GetBarHasClosedStatus() == BHCS_BAR_HAS_NOT_CLOSED)
sc.SupportTradingScaleOut = 1; else if (sc.GetBarHasClosedStatus() == BHCS_BAR_HAS_CLOSED) { sc.SupportTradingScaleOut = 0; //Submit order to create an opposite order with attached orders does not create attached orders, only the opposite order. |
[2025-07-15 13:44:29] |
ForgivingComputers.com - Posts: 1114 |
Yes that is the code I meant to use. Not sure why it isn't working for you.
|
[2025-07-17 00:29:15] |
@sstfrederik - Posts: 410 |
it is likely that the order is not fully processed and you already set ScaleOut back to 1. you should likely check for the order to be in SCT_OSC_OPEN status before switching the ScaleOut state.
Date Time Of Last Edit: 2025-07-17 17:02:55
|
[2025-07-28 23:02:17] |
rajeshh - Posts: 25 |
Thanks for your post @sstfrederik. I am now doing something even more straightforward. I initially open a position with a long market order at the close of bar (bar 1 let's say), and at the close of the next bar (bar 2), open an opposite order with ScaleOut = 0, but it does not work, even though ScaleOut is logged as 0 in the log message. It does work on the order opened at the close of bar 3. So it's almost as if the setting is bar late. SCSFExport scsf_ScaleInOutDemo3(SCStudyInterfaceRef sc)
{ if (sc.SetDefaults) { sc.GraphName = "ScaleInOut Demo 3"; sc.AutoLoop = 0; sc.GraphRegion = 0; sc.MaximumPositionAllowed = 10; sc.AllowMultipleEntriesInSameDirection = true; sc.SupportAttachedOrdersForTrading = true; sc.UseGUIAttachedOrderSetting = false; // Only 1 trade for each Order Action type is allowed per bar. sc.AllowOnlyOneTradePerBar = false; sc.AllowEntryWithWorkingOrders = true; sc.AllowOppositeEntryWithOpposingPositionOrOrders = true; // This is false by default. Orders will go to the simulation system always. sc.SendOrdersToTradeService = false; sc.FreeDLL = 1; return; } SCString msg; // Only run study at close of bar. have tried combinations of BAR_HAS_NOT_CLOSED etc but does not change outcome if (sc.GetBarHasClosedStatus(sc.Index) != BHCS_BAR_HAS_CLOSED) return; sc.SupportTradingScaleIn = 1; s_SCPositionData PositionData; sc.GetTradePosition(PositionData); if ( PositionData.PositionQuantity ==0 ){ sc.SupportTradingScaleOut = 1; // Example: Buy Market Order with attached orders s_SCNewOrder order; order.OrderType = SCT_ORDERTYPE_MARKET; order.OrderQuantity = 3; order.Target1Offset = .50; // 50 ticks above order.Stop1Offset = -.50; // 50 ticks below order.AttachedOrderStop1Type = SCT_ORDERTYPE_STOP; order.AttachedOrderTarget1Type = SCT_ORDERTYPE_LIMIT; order.OCOGroup1Quantity=3; // Submit first buy order int result = sc.BuyEntry(order); if ( result > 0) { msg.Format("index=%u,1st Orderid = %u, sc.SupportTradingScaleOut = %u, sc.ArraySize-1 =%u ", sc.Index, order.InternalOrderID, sc.SupportTradingScaleOut, sc.ArraySize-1); sc.AddMessageToLog(msg, 1); } } else if ( PositionData.PositionQuantity >0 ){ // Disable scale-out for next order sc.SupportTradingScaleOut = 0; if (sc.SupportTradingScaleOut == 0){ s_SCNewOrder order2; // Submit new sell order with attached orders order2.Target1Offset = -.10; // 10 ticks below entry order2.Stop1Offset = .10; // 10 ticks above entry order2.OrderType = SCT_ORDERTYPE_STOP; order2.Price1 = sc.Low[sc.Index] -sc.TickSize; order2.OrderQuantity = 1; order2.OCOGroup1Quantity=1; sc.SellEntry(order2); // This should be treated as a new parent order, with attached orders. Except it isnt. msg.Format("index=%u,Reversal Orderid = %u, sc.SupportTradingScaleOut = %u, sc.ArraySize-1=%u", sc.Index, order2.InternalOrderID, sc.SupportTradingScaleOut,sc.ArraySize-1); sc.AddMessageToLog(msg, 1); } } } Date Time Of Last Edit: 2025-07-28 23:07:08
|
[2025-07-28 23:57:35] |
@sstfrederik - Posts: 410 |
The ScaleIn and ScaleOut settings are valid for the calculation cycle it is called in. In other words if you change it it will only work in the next cycle. Your use case you can simply set a persistent variable to trigger the order on the next calculation cycle. btw. the target and stop offset are price values not ticks. SCSFExport scsf_ScaleInOutDemo3(SCStudyInterfaceRef sc) { if (sc.SetDefaults) { sc.GraphName = "ScaleInOut Demo 3"; sc.AutoLoop = 0; sc.GraphRegion = 0; sc.MaximumPositionAllowed = 10; sc.AllowMultipleEntriesInSameDirection = true; sc.SupportAttachedOrdersForTrading = true; sc.UseGUIAttachedOrderSetting = false; // Only 1 trade for each Order Action type is allowed per bar. sc.AllowOnlyOneTradePerBar = false; sc.AllowEntryWithWorkingOrders = true; sc.AllowOppositeEntryWithOpposingPositionOrOrders = true; // This is false by default. Orders will go to the simulation system always. sc.SendOrdersToTradeService = false; return; } int& setorder = sc.GetPersistentInt(0); SCString msg; if ( setorder == 1 ){ setorder = 0; // Disable scale-out for next order if (sc.SupportTradingScaleOut == 0){ s_SCNewOrder order2; // Submit new sell order with attached orders order2.Target1Offset = -.10; // 10 ticks below entry order2.Stop1Offset = .10; // 10 ticks above entry order2.OrderType = SCT_ORDERTYPE_STOP; order2.Price1 = sc.Low[sc.Index] -sc.TickSize; order2.OrderQuantity = 1; order2.OCOGroup1Quantity=1; sc.SellEntry(order2); // This should be treated as a new parent order, with attached orders. Except it isnt. msg.Format("index=%u,Reversal Orderid = %u, sc.SupportTradingScaleOut = %u, sc.ArraySize-1=%u", sc.Index, order2.InternalOrderID, sc.SupportTradingScaleOut,sc.ArraySize-1); sc.AddMessageToLog(msg, 1); sc.SupportTradingScaleOut = 1; } } // Only run study at close of bar. have tried combinations of BAR_HAS_NOT_CLOSED etc but does not change outcome if (sc.GetBarHasClosedStatus(sc.Index) != BHCS_BAR_HAS_CLOSED) return; sc.SupportTradingScaleIn = 1; //sc.SupportTradingScaleOut = 0; s_SCPositionData PositionData; sc.GetTradePosition(PositionData); if ( PositionData.PositionQuantity ==0 ){ sc.SupportTradingScaleOut = 1; // Example: Buy Market Order with attached orders s_SCNewOrder order; order.OrderType = SCT_ORDERTYPE_MARKET; order.OrderQuantity = 3; order.Target1Offset = .50; // 50 ticks above order.Stop1Offset = -.50; // 50 ticks below order.AttachedOrderStop1Type = SCT_ORDERTYPE_STOP; order.AttachedOrderTarget1Type = SCT_ORDERTYPE_LIMIT; order.OCOGroup1Quantity=3; // Submit first buy order int result = sc.BuyEntry(order); if ( result > 0) { msg.Format("index=%u,1st Orderid = %u, sc.SupportTradingScaleOut = %u, sc.ArraySize-1 =%u ", sc.Index, order.InternalOrderID, sc.SupportTradingScaleOut, sc.ArraySize-1); sc.AddMessageToLog(msg, 1); } } else if ( PositionData.PositionQuantity >0 ){ setorder = 1; sc.SupportTradingScaleOut = 0; return; } } |
[2025-07-29 20:42:27] |
rajeshh - Posts: 25 |
Thanks @sstfrederik again for the prompt help. Your code does work, although in my real example, the "next" cycle when sc.SupportTradingScaleOut = 0 has to work is the close of the bar, which I understand would be the last calcuation cycle for that bar, so then its not clear when I would set the persistent variable ( it would have to be something like a time check for a few seconds before the bar is about to close). Not sure how I didnt find this article in my earlier search, but I found this thread Executing orders at bar close which discusses the same topic, and says not to use GetBarClosedStatus and there is code from somebody that is using the clock to determine when a bar is about to close and then SC support posted saying they have added a function - sc.IsLastBarClosedBasedOnElapsedTime (sc.ChartNumber) which will give me what I need. I did some initial testing with this, and it is working, however as the last comment on that thread says, it only works in live mode, whereas ideally I need it to work in replay mode as well.
Date Time Of Last Edit: 2025-07-29 21:22:24
|
[2025-07-29 22:39:58] |
@sstfrederik - Posts: 410 |
Many roads lead to Rome.
|
To post a message in this thread, you need to log in with your Sierra Chart account: