Support Board
Date/Time: Tue, 26 Nov 2024 01:53:13 +0000
Post From: sc.EarliestUpdateSubgraphDataArrayIndex seems broken with Study/Price Overlay
[2024-01-19 22:11:14] |
User719512 - Posts: 264 |
FYI Sierra Chart Engineering and others interested parties, I have found a workaround/solution that appears to work, at least for the test cases I need and a few charts I tested against. Basically, from the source chart (chart#1), call RecalculateChart, and maintain a persistent variable to ignore the recalculation when raised from itself before proceeding normally. This does require using manual looping (which is really the best way to write a study anyway). Also there is logic for a "full recalculation" where the study should clear/reset any state/subgraphs/pointers/etc when the update index is 0. The sample code below has these patterns, and for your own studies, care and understanding need to be taken to ensure correct behavior. This pattern should work until such time as Sierra Engineering fixes how sc.EarliestUpdateSubgraphDataArrayIndex is managed across all charts. SCSFExport scsf_123_RedrawWithOverlay(SCStudyInterfaceRef sc) { SCString msg; int& r_RecalculateFlag = sc.GetPersistentIntFast(5); if (sc.SetDefaults) { sc.GraphName = "123_RedrawWithOverlay"; sc.AutoLoop = 0; // DO NOT USE AutoLoop, manual only sc.DrawZeros = 0; sc.UpdateAlways = 1; sc.Subgraph[0].Name = "Value"; sc.Subgraph[0].DrawStyle = DRAWSTYLE_LINE; sc.Subgraph[0].PrimaryColor = RGB(0, 255, 0); r_RecalculateFlag = 0; return; } // manual looping index so we can override sc.UpdateStartIndex when needed int scUpdateStartIndex; scUpdateStartIndex = sc.UpdateStartIndex; if (r_RecalculateFlag == 1) { // ensure we are being called with IsFullRecalculation and not just on a timer/event if (sc.IsFullRecalculation) { r_RecalculateFlag = 0; } return; } if (scUpdateStartIndex == 0) { // clear all SGs so Recalculate works properly for (int i = 0; i < SC_SUBGRAPHS_AVAILABLE; i++) { for (int barIndex = 0; barIndex < sc.ArraySize; barIndex++) { sc.Subgraph[i][barIndex] = 0; } } } bool shouldRecalculateChart = false; int bucketSize = 10; // even number is best for (int barIndex = scUpdateStartIndex; barIndex < sc.ArraySize; barIndex++) { if (sc.GetBarHasClosedStatus(barIndex) == BHCS_BAR_HAS_NOT_CLOSED) { return; } if ((barIndex % bucketSize) < bucketSize / 2) { if ((barIndex % bucketSize) == 0) { // show all the SG data back to index 0 // by setting value to 0 for (int barIndex = 0; barIndex < sc.ArraySize; barIndex++) { sc.Subgraph[0][barIndex] = sc.Low[barIndex]; } shouldRecalculateChart = true; msg.Format("%d: Show all", barIndex); sc.AddMessageToLog(msg, 1); if (!sc.IsFullRecalculation) { sc.EarliestUpdateSubgraphDataArrayIndex = 0; } } else { // just update this index sc.Subgraph[0][barIndex] = sc.Low[barIndex]; } } else if ((barIndex % bucketSize) == bucketSize / 2) { // hide all the SG data back to index 0 // by setting value to 0 for (int barIndex = 0; barIndex < sc.ArraySize; barIndex++) { sc.Subgraph[0][barIndex] = 0; } shouldRecalculateChart = true; msg.Format("%d: Hide all", barIndex); sc.AddMessageToLog(msg, 1); if (!sc.IsFullRecalculation) { sc.EarliestUpdateSubgraphDataArrayIndex = 0; } } } if (shouldRecalculateChart) { sc.RecalculateChart(sc.ChartNumber); r_RecalculateFlag = 1; } } |