Support Board
Date/Time: Mon, 21 Apr 2025 13:08:36 +0000
[Programming Help] - ACSIL sc.GetOrderFillArraySize() returning transient 0 after chart relo
View Count: 96
[2025-04-17 23:23:04] |
User351137 - Posts: 14 |
sc.GetOrderFillArraySize() returning transient 0 after chart reload/timeframe change? Hello Sierra Chart Support & Community, I'm developing a custom ACSIL study where I need to reliably detect when a new order fill occurs for the chart's symbol and trade account. My goal is to trigger an action immediately after a fill happens. The most straightforward approach seemed to be monitoring the total number of fills using sc.GetOrderFillArraySize() and comparing its current value to the value from the previous study execution, stored in a persistent variable. To isolate and demonstrate a potential issue with this approach, I created a very simple test study (scsf_DebugFillCountChange) that does nothing but log a message whenever the value returned by sc.GetOrderFillArraySize() differs from the previously stored value. The study uses sc.UpdateAlways = 1 and requires sc.MaintainTradeStatisticsAndTradesData = 1. Here is the code for the test study: #include "sierrachart.h" SCSFExport scsf_DebugFillCountChange(SCStudyInterfaceRef sc) { // --- SetDefaults Block --- if (sc.SetDefaults) { sc.GraphName = "Debug Fill Count Change"; sc.StudyDescription = "Logs when sc.GetOrderFillArraySize() changes value compared to the previous call. Used to demonstrate potential instability after chart reloads."; sc.AutoLoop = 0; sc.UpdateAlways = 1; sc.GraphRegion = 0; sc.HideStudy = 1; sc.MaintainTradeStatisticsAndTradesData = 1; // Essential for fill data // Persistent variable for the last known fill count. // Initialized to -1 to reliably detect the very first run. sc.SetPersistentInt(1, -1); // PreviousFillCount return; } // --- End SetDefaults --- // --- Main Logic --- // Optional: Skip checks during full recalc or data download if (sc.IsFullRecalculation || sc.DownloadingHistoricalData) { return; // Data is definitely not stable during these phases } // Get persistent variable int& PreviousFillCount = sc.GetPersistentInt(1); // Get current fill count int CurrentFillCount = sc.GetOrderFillArraySize(); // --- Check for Initialization or Change --- // Case 1: First run initialization if (PreviousFillCount == -1) { PreviousFillCount = CurrentFillCount; // Store initial value SCString InitMsg; InitMsg.Format("DebugFillCountChange: Initial fill count set to %d (at Index %d)", PreviousFillCount, sc.Index); sc.AddMessageToLog(InitMsg, 0); } // Case 2: Regular check (Initialization complete) else if (CurrentFillCount != PreviousFillCount) { // Change detected! Log the details. SCString DbgMsg; DbgMsg.Format(">>> Fill Count Changed! CurrentFills=%d, PrevFills=%d (Checked at Index %d)", CurrentFillCount, PreviousFillCount, sc.Index ); sc.AddMessageToLog(DbgMsg, 1); // Log with 1 for visibility // Update the persistent state AFTER logging the change PreviousFillCount = CurrentFillCount; } // Case 3: No change // -> Do nothing } // End scsf_DebugFillCountChange Observed Behavior & Log Output: When I add this study to a chart that already has existing order fills (e.g., 10 fills) and then simply change the chart's timeframe (which triggers a chart reload), I consistently see the following pattern in the Message Log: 2025-04-18 01:26:54.229 | Chart: ESM25-CME[M] 3 Min #1 | Study: Debug Fill Count Change | DebugFillCountChange: Initial fill count set to 10 (at Index 6409) 2025-04-18 01:26:54.234 | Socket (3) | Socket gracefully closed by remote side. 2025-04-18 01:26:54.234 | Socket (3) | Closed. 2025-04-18 01:27:04.302 | ESM25-CME[M] 10 Min #1 | Reloading chart. 2025-04-18 01:27:08.430 | ESM25-CME[M] 10 Min #1 | StartDateTimeForLoadingOrderFills: 00:00:00 2025-04-18 01:27:08.440 | ESM25-CME[M] 10 Min #1 | Chart data loading complete. 2025-04-18 01:27:08.456 | Chart: ESM25-CME[M] 10 Min #1 | Study: Debug Fill Count Change | >>> Fill Count Changed! CurrentFills=0, PrevFills=10 (Checked at Index 1949) 2025-04-18 01:27:08.498 | Chart: ESM25-CME[M] 10 Min #1 | Study: Debug Fill Count Change | >>> Fill Count Changed! CurrentFills=10, PrevFills=0 (Checked at Index 1949) Analysis of the Log: 1. Before Reload: The study correctly identified and stored PreviousFillCount = 10. 2. Reload Triggered: Changing the timeframe triggers Reloading chart. 3. Fill Loading Starts: The message StartDateTimeForLoadingOrderFills: 00:00:00 appears. 4. Data Loading Complete: Chart data loading complete. appears. 5. IMMEDIATELY AFTER (01:27:08.456): My study runs. sc.GetOrderFillArraySize() returns 0. The comparison CurrentFills(0) != PrevFills(10) is TRUE, triggering the first >>> Fill Count Changed! log. PreviousFillCount is then updated to 0. 6. A Moment Later (01:27:08.498): The study runs again (likely due to sc.UpdateAlways=1). Now, sc.GetOrderFillArraySize() returns the correct value 10. The comparison CurrentFills(10) != PrevFills(0) is TRUE again, triggering the second >>> Fill Count Changed! log. PreviousFillCount is finally updated to the correct value 10. The Problem: The function sc.GetOrderFillArraySize() appears to return a transient value of 0 immediately after a chart reload (specifically, right after the StartDateTimeForLoadingOrderFills phase seems to complete), even when historical fills exist. It only returns the correct count slightly later. This transient 0 causes my fill detection logic (CurrentFillCount != PreviousFillCount) to trigger incorrectly immediately after a reload or timeframe change. Question: Is this transient behavior of sc.GetOrderFillArraySize() (returning 0 temporarily after a reload) expected? Is there a recommended, reliable way in ACSIL to ensure that the order fill list (and thus the count returned by sc.GetOrderFillArraySize()) is fully loaded and stable before querying its size after a chart reload or timeframe change? Currently, the only workaround seems to be adding a delay (e.g., skipping several calculation cycles after detecting a reload event), but a more direct method to check for data stability would be preferred. Thank you for any insights or guidance. Date Time Of Last Edit: 2025-04-17 23:44:01
|
[2025-04-18 07:41:37] |
Sierra_Chart Engineering - Posts: 19285 |
The documentation has been updated to explain this. More information is here: Trade Activity Log: Trade Activity Not Displaying or Clearing (Improving Trade Activity Query Performance) Question: Is this transient behavior of sc.GetOrderFillArraySize() (returning 0 temporarily after a reload) expected? Is there a recommended, reliable way in ACSIL to ensure that the order fill list (and thus the count returned by sc.GetOrderFillArraySize()) is fully loaded and stable before querying its size after a chart reload or timeframe change? Sierra Chart Support - Engineering Level Your definitive source for support. Other responses are from users. Try to keep your questions brief and to the point. Be aware of support policy: https://www.sierrachart.com/index.php?l=PostingInformation.php#GeneralInformation For the most reliable, advanced, and zero cost futures order routing, use the Teton service: Sierra Chart Teton Futures Order Routing |
[2025-04-18 09:49:34] |
User431178 - Posts: 651 |
At the risk of sounding dumb, why not use greater than comparison instead of not equal? I mean the fill list is not going to get smaller when an order is filled, is it? else if (CurrentFillCount > PreviousFillCount) Maybe there is one situation where upon reload the list is smaller, depending on the order fills loaded in the chart? Order Fills Number of Days to Load -> Chart Settings: Order Fills Number of Days to Load (Chart >> Chart Settings >> Trading menu) If that is a valid concern, then I am sure that could also be handled without too much of a problem. |
[2025-04-18 10:21:31] |
TedMar - Posts: 191 |
My Workaround for transient “0” from sc.GetOrderFillArraySize() after chart reload I’ve updated the debug study to reliably skip the transient “0” value that appears immediately after a chart reload or timeframe change. Since fills never actually disappear, the workaround simply ignores any drop to zero when the previous count was greater than zero. Workaround summary: Initialize PreviousFillCount on the very first run. On every call, read CurrentFillCount = sc.GetOrderFillArraySize(). If CurrentFillCount == 0 and PreviousFillCount > 0, skip that cycle (treat as transient). Otherwise, log any real change (CurrentFillCount != PreviousFillCount) and update the stored count. This approach is much simpler than trying to detect every reload scenario, and it handles both manual Reload & Recalculate and timeframe switches. #include "sierrachart.h" // Debug study: skip transient zero and only log real fill-count changes SCSFExport scsf_DebugFillCountChange_Simple(SCStudyInterfaceRef sc) { if (sc.SetDefaults) { sc.GraphName = "Debug Fill Count + Simple Skip"; sc.StudyDescription = "Logs fill-count changes, skips any transient 0."; sc.AutoLoop = 0; // No auto-loop over bars sc.UpdateAlways = 1; // Always call, even without new ticks sc.GraphRegion = 0; // Draw in the main chart region sc.HideStudy = 1; // Keep this study hidden sc.MaintainTradeStatisticsAndTradesData = 1; // Required for fill data // --- Persistent variables --- sc.SetPersistentInt(0, 0); // IsInitialized flag sc.SetPersistentInt(1, -1); // PreviousFillCount return; } // Do not run during a full recalculation or while downloading historical data if (sc.IsFullRecalculation || sc.DownloadingHistoricalData) return; // Retrieve persistent variables int& IsInitialized = sc.GetPersistentInt(0); int& PreviousFillCount = sc.GetPersistentInt(1); int CurrentFillCount = sc.GetOrderFillArraySize(); // First-time initialization if (IsInitialized == 0) { if (CurrentFillCount == 0) return; // still loading, skip until the real count arrives, is required if you want to duplicate chart with the study PreviousFillCount = CurrentFillCount; IsInitialized = 1; SCString initMsg; initMsg.Format("Init: PrevFillCount=%d", PreviousFillCount); sc.AddMessageToLog(initMsg, 0); return; } // Skip any transient drop to zero immediately after reload if (CurrentFillCount == 0 && PreviousFillCount > 0) { sc.AddMessageToLog("Skipping transient zero after reload", 0); PreviousFillCount = 0; // Sync up so next real change is detected return; } // Log any real change in fill count if (CurrentFillCount != PreviousFillCount) { SCString logMsg; logMsg.Format(">>> Fill count changed: Prev=%d, Curr=%d", PreviousFillCount, CurrentFillCount); sc.AddMessageToLog(logMsg, 1); PreviousFillCount = CurrentFillCount; } } With this version, every time the chart reloads you’ll see exactly one “Skipping transient zero after reload” entry, followed by a single correct fill-count change. Let me know if this solves the issue in all your reload scenarios! — Ted Date Time Of Last Edit: 2025-04-18 11:01:15
|
To post a message in this thread, you need to log in with your Sierra Chart account: