Login Page - Create Account

Support Board


Date/Time: Mon, 25 Nov 2024 23:25:21 +0000



sc.EarliestUpdateSubgraphDataArrayIndex seems broken with Study/Price Overlay

View Count: 349

[2024-01-18 21:34:19]
User719512 - Posts: 264
Hello Sierra Chart Engineering,

There seems to be issues with Study/Price Overlay when referencing a lower time frame chart from a higher time frame chart.

I have created a small study to demonstrate/reproduce this issue.
It simply draws an SG for all bars at the specified value (ON) every N bars and sets the SG value to 0 (OFF) every N bars as well.

Repro Steps:
Build this study and put on chart#1, a 1 second chart.
Add Study/Price Overlay to chart#2, 1 second chart, and reference the study.
Add Study/Price Overlay to chart#3, 10 second chart, and reference the study.

Notice that chart#2 updates as expected when the study changes from ON/OFF/ON.
Notice that chart#3 does NOT update as expected when the study changes from ON/OFF/ON.

sc.EarliestUpdateSubgraphDataArrayIndex seems broken with Study/Price Overlay when it is on a higher timeframe chart from the source chart.

Trying to work around the issue by calling sc.RecalculateChart(sc.ChartNumber) in chart#1 is not only problmatic and inefficient, it also leads to chart#1 to stop repsponding as it seems to put the chart into a infinite/bad/intensive loop.

Changing Study/Price Overlay to use Nearest or Containing has no effect.

Also, since other studies might be referencing this chart or this study via sc.GetStudyArrayFromChart(), how does sc.EarliestUpdateSubgraphDataArrayIndex affect these calls? It would seem other studies do not have the same access to this variable as the docs mention studies like "Study/Price Overlay study, the Color Bar Based on Alert Condition study, the Spreadsheet Studies" have in https://www.sierrachart.com/index.php?page=doc/ACSIL_Members_Variables_And_Arrays.html#scEarliestUpdateSubgraphDataArrayIndex.

Can you please comment on how studies using sc.GetStudyArrayFromChart() are impacted by changes to sc.EarliestUpdateSubgraphDataArrayIndex?


Before posting this, I did search for more info, and neither of these seemed to indicate anything that would point to a problem in my code.
Study/Price Overlay; Changes to source study sc.Subgraph[]. variables are not reflected
Is there a way to cause chart updates with ACSIL?


Sample Code:

SCSFExport scsf_123_RedrawWithOverlay(SCStudyInterfaceRef sc)
{
  SCString msg;

  if (sc.SetDefaults)
  {
    sc.GraphName = "123_RedrawWithOverlay";
    sc.AutoLoop = 1; //Automatic looping is enabled.
    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);

    return;
  }

  if (sc.GetBarHasClosedStatus() == BHCS_BAR_HAS_NOT_CLOSED)
  {
    return;
  }

  if (sc.Index < sc.ArraySize - 2)
  {
    // only process if on last bar on chart
    return;
  }

  int bucketSize = 10; // even number is best

  if ((sc.Index % bucketSize) < bucketSize/2)
  {
    if ((sc.Index % bucketSize) == 0)
    {
      // show all the SG data back to index 0
      // by setting value to 0
      for (int barIndex = 0; barIndex <= sc.Index; barIndex++)
      {
        sc.Subgraph[0][barIndex] = sc.Low[barIndex];
      }

      if (!sc.IsFullRecalculation)
      {
        sc.EarliestUpdateSubgraphDataArrayIndex = 0;
        msg.Format("%d: Show all", sc.Index);
        sc.AddMessageToLog(msg, 1);
      }
    }
    else
    {
      // just update this index
      sc.Subgraph[0][sc.Index] = sc.Low[sc.Index];
    }
  }
  else
  if ((sc.Index % bucketSize) == bucketSize / 2)
  {
    // hide all the SG data back to index 0
    // by setting value to 0
    for (int barIndex = 0; barIndex <= sc.Index; barIndex++)
    {
      sc.Subgraph[0][barIndex] = 0;
    }

    if (!sc.IsFullRecalculation)
    {
      sc.EarliestUpdateSubgraphDataArrayIndex = 0;
      msg.Format("%d: Hide all", sc.Index);
      sc.AddMessageToLog(msg, 1);
    }
  }
}

[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;
  }
}

[2024-01-22 15:27:35]
Sierra_Chart Engineering - Posts: 17178
Also, since other studies might be referencing this chart or this study via sc.GetStudyArrayFromChart(), how does sc.EarliestUpdateSubgraphDataArrayIndex affect these calls?
There are no ACSIL function calls that will ever be affected by sc.EarliestUpdateSubgraphDataArrayIndex.

This variable does not work across charts:

This pattern should work until such time as Sierra Engineering fixes how sc.EarliestUpdateSubgraphDataArrayIndex is managed across all charts.
It is only used within a single chart.

What you need to do to solve the problem you are having, whatever it is and it is beyond the scope of our support to understand this, is to not use the Study/Price Overlay study and instead do direct referencing, in your custom study to reference data from other charts to specifically accomplish what you need.

Refer to:
Referencing Other Time Frames and Symbols When Using the ACSIL: Referencing Data from Other Time Frames By Direct Referencing of the Other Timeframe
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
Date Time Of Last Edit: 2024-01-22 15:28:28
[2024-01-22 16:31:04]
User719512 - Posts: 264
Thanks for the reply Sierra Chart Engineering,

From your reply above
This variable does not work across charts:

I did not get that from the docs at https://www.sierrachart.com/index.php?page=doc/ACSIL_Members_Variables_And_Arrays.html#scEarliestUpdateSubgraphDataArrayIndex, so thanks for the clarification.

Guess I was confused by the docs at Study/Price Overlay Study: Data Changing at Chart Bars Earlier Than Being Referenced in Source Chart and the part about:
If you have developed your own custom study, and it changes its data at chart bars earlier than the last bar in the chart, at times when there is not a full recalculation, then for the Study/Price Overlay study to be aware of those changes use the sc.EarliestUpdateSubgraphDataArrayIndex variable.

There is no mention about this only working on the same chart, and not other charts which is my main use case for Study/Price Overlay for built-in studies and custom studies.

Thanks again for your reply on this matter.

To post a message in this thread, you need to log in with your Sierra Chart account:

Login

Login Page - Create Account