Login Page - Create Account

Support Board


Date/Time: Fri, 14 Mar 2025 18:05:38 +0000



[Programming Help] - must recalculate the study to see correct values?

View Count: 1102

[2022-06-24 02:16:41]
User133994 - Posts: 80
To whom it may concern,

Attached is the ACSIL custom study code that I'm using. It works "as expected" when I press the "recalculate" menu item, but other times (i.e. when SC does a full recalculate automatically) which happens often, the study doesn't show any useful information. Rather, the region just paints "bars" at full height without a scale. I think I saw "NaN" at one time, but not anymore.

Nonetheless, I've tried adding the exception after the default block of "isfullrecalculation" to not run the code, but I need the historical bars to show the results of the study--so that won't work.

It is doing "automatic looping" so I'm not doing manual anything.

Please help me find the bug where it somehow thinks all the data is garbage and paints nothing. And, also, why is it all "fixed" when I press the "recalculate" item on the "chart" menu? I wonder why all the other "fullrecalculation" events cause garbage output (until it is cleaned up when I press the "recalculate" menu item)?

Thanks in advance!


SCSFExport scsf_DynamicHHLL(SCStudyInterfaceRef sc)
{

  SCSubgraphRef Subgraph_HH = sc.Subgraph[0];
  SCSubgraphRef Subgraph_LL = sc.Subgraph[1];

  SCInputRef Input_Study1 = sc.Input[0];
  SCInputRef Input_Study1Subgraph = sc.Input[1];

  SCInputRef Input_Lookback = sc.Input[4];
  SCInputRef Input_LookbackSubgraph = sc.Input[5];

  // Set configuration variables
  
  if (sc.SetDefaults)
  {
    // Set the configuration and defaults
    
    sc.GraphName = "DynHHLL v 0.05";
    sc.GraphRegion = 4;
    
    // Set the Length input and default it to 30
Input_Lookback.Name = "Input Study to determine Lookback Range";
    Input_Lookback.SetStudyID(100);
    
    Input_LookbackSubgraph.Name = "Lookback Study Subgraph";
    Input_LookbackSubgraph.SetSubgraphIndex(0);

    Subgraph_HH.Name = "DynHighestHigh";
    Subgraph_HH.DrawStyle = DRAWSTYLE_LINE;
    Subgraph_HH.PrimaryColor = RGB(0,255,0);

    Subgraph_LL.Name = "DynLowestLow";
    Subgraph_LL.DrawStyle = DRAWSTYLE_LINE;
    Subgraph_LL.PrimaryColor = RGB(0,255,255);

    Input_Study1.Name = "Input Study 1";
    Input_Study1.SetStudyID(11);

    Input_Study1Subgraph.Name = "Study 1 Subgraph";
    Input_Study1Subgraph.SetSubgraphIndex(0);


    sc.AutoLoop = 1;
    
    return;
  }
  
  
if(sc.ArraySize<50) return;

  // Get the subgraph specified with the Study 1
  // Subgraph input from the study specified with
  // the Input Study 1 input.
  SCFloatArray Study1Array;
  sc.GetStudyArrayUsingID(Input_Study1.GetStudyID(),Input_Study1Subgraph.GetSubgraphIndex(),Study1Array);

  SCFloatArray LookbackStudyArray;
  sc.GetStudyArrayUsingID(Input_Lookback.GetStudyID(),Input_LookbackSubgraph.GetSubgraphIndex(),LookbackStudyArray);


  int lookback = static_cast<int>(LookbackStudyArray[sc.Index]);
  int total =0;
  float RefStudyCurrentValue = 0.0;
  SCString DebugString;

  int& r_LastLookback = sc.GetPersistentInt(1);

  //ensure lookback is positive at all times
  if (lookback <= 0){
   lookback = 1;
   r_LastLookback = 1;
  }else if(r_LastLookback <= 0){
   lookback = 5;
   r_LastLookback = 5;
  }else{
   r_LastLookback = lookback;
  }

  DebugString.Format("lookback == : %d", lookback);
  sc.AddMessageToLog(DebugString, 0);

  Subgraph_HH[sc.Index] =sc.GetHighest(Study1Array, lookback);
  Subgraph_LL[sc.Index] =sc.GetLowest(Study1Array, lookback);

  DebugString.Format("highest == : %f", sc.GetHighest(Study1Array, lookback));
  sc.AddMessageToLog(DebugString, 0);
  DebugString.Format("lowest == : %f", sc.GetLowest(Study1Array, lookback));
  sc.AddMessageToLog(DebugString, 0);

}


I could try to live with the menu item work around...but everytime I press the "apply" button after changing a study attribute it ruins most all of my indicators (and what i thought I applied is masked by the garbage output of this indicator)...so I have to exit the study dialogue, find the menu recalc item, and click it. Very difficult to work that way.

Thanks again for your insights.
Date Time Of Last Edit: 2022-06-24 02:18:08
[2022-06-24 18:37:19]
User133994 - Posts: 80
Pictures help..so top picture is what it should look like all the time. However, when SC does a recalc for some reason (after hitting "apply" on a study dialogue) what I see is in the bottom picture. Any ideas?

NOTE: I'm only discussing the bottom pane in these pictures--thus it is *zoomed* into full view.

Top PICTURE:
https://www.sierrachart.com/image.php?Image=1656095740176.png


Bottom PICTURE:
https://www.sierrachart.com/image.php?Image=1656095648573.png
Date Time Of Last Edit: 2022-06-24 18:38:30
[2022-06-24 23:21:06]
User133994 - Posts: 80
SC Engineers:

I've isolated the issue. Now the study region only shows 2 subgraphs (below). And, the scale of region is displaying NaN for


Subgraph_HH[sc.Index] =sc.GetHighest(Study1Array, lookback);

Subgraph_LL[sc.Index] =sc.GetLowest(Study1Array, lookback);

However, when I test with lookback =5; (yes, a fixed number); but even with this very restricted test setup, NaN is still appearing? And, yes, the study still repaints correctly in the region when I manually click the "recalculate" menu item...weird.

Also, I have debug statements that show just valid floating point numbers being stored in each of the Subgraph_HH and Subgraph_LL arrays, these are clearly not NaN numbers? I've implemented the following debugging (including a NaN test):



  hhanswer =sc.GetHighest(Study1Array, lookback);
  llanswer =sc.GetLowest(Study1Array, lookback);

  if (Input_DetailedLogging.GetYesNo() && LastLogMessageIdentifier != 3)
  {
   LastLogMessageIdentifier = 3;
  DebugString.Format("hhanswer == : %f", hhanswer);
  sc.AddMessageToLog(DebugString, 0);
  DebugString.Format("llanswer == : %f", llanswer);
  sc.AddMessageToLog(DebugString, 0);
  }

  if (isnan(hhanswer)){
   Subgraph_HH[sc.Index] = 0;
  }else{
   Subgraph_HH[sc.Index] = hhanswer;
  }

  if (isnan(llanswer)){
   Subgraph_LL[sc.Index] = 0;
  }else{
   Subgraph_LL[sc.Index] = llanswer;
  }


And it doesn't help!? The Subgraph_LL and Subgraph_HH both pass the isnan() test...and, yet, still paint NaN in the study region that is only isolated to Subgraph_LL and Subgraph_HH?

Also, the debug strings are printing correct information (small portion shown below--[1158.0, 0.0, 1559.0, 0.0, ...] is printing while NaN is showing in the region?):
Chart: Replay 60X: ESU22_FUT_CME [CV][M] 1 Min #4 | Study: DynHHLL v 0.09 | lookback == : 5 | 2022-06-24 18:52:01.073
Chart: Replay 60X: ESU22_FUT_CME [CV][M] 1 Min #4 | Study: DynHHLL v 0.09 | sc.Index == : 0.000000 | 2022-06-24 18:52:01.073
Chart: Replay 60X: ESU22_FUT_CME [CV][M] 1 Min #4 | Study: DynHHLL v 0.09 | Study1Array[sc.Index] == : 0.000000 | 2022-06-24 18:52:01.073
Chart: Replay 60X: ESU22_FUT_CME [CV][M] 1 Min #4 | Study: DynHHLL v 0.09 | hhanswer == : 1158.000000 | 2022-06-24 18:52:01.073
Chart: Replay 60X: ESU22_FUT_CME [CV][M] 1 Min #4 | Study: DynHHLL v 0.09 | llanswer == : 0.000000 | 2022-06-24 18:52:01.073
Chart: Replay 60X: ESU22_FUT_CME [CV][M] 1 Min #4 | Study: DynHHLL v 0.09 | lookback == : 5 | 2022-06-24 18:52:01.073
Chart: Replay 60X: ESU22_FUT_CME [CV][M] 1 Min #4 | Study: DynHHLL v 0.09 | sc.Index == : 0.000000 | 2022-06-24 18:52:01.073
Chart: Replay 60X: ESU22_FUT_CME [CV][M] 1 Min #4 | Study: DynHHLL v 0.09 | Study1Array[sc.Index] == : 440.500000 | 2022-06-24 18:52:01.073
Chart: Replay 60X: ESU22_FUT_CME [CV][M] 1 Min #4 | Study: DynHHLL v 0.09 | hhanswer == : 1559.000000 | 2022-06-24 18:52:01.073
Chart: Replay 60X: ESU22_FUT_CME [CV][M] 1 Min #4 | Study: DynHHLL v 0.09 | llanswer == : 0.000000 | 2022-06-24 18:52:01.073
Chart: Replay 60X: ESU22_FUT_CME [CV][M] 1 Min #4 | Study: DynHHLL v 0.09 | lookback == : 5 | 2022-06-24 18:52:02.049
Chart: Replay 60X: ESU22_FUT_CME [CV][M] 1 Min #4 | Study: DynHHLL v 0.09 | sc.Index == : 0.000000 | 2022-06-24 18:52:02.049
Chart: Replay 60X: ESU22_FUT_CME [CV][M] 1 Min #4 | Study: DynHHLL v 0.09 | Study1Array[sc.Index] == : 0.000000 | 2022-06-24 18:52:02.049
Chart: Replay 60X: ESU22_FUT_CME [CV][M] 1 Min #4 | Study: DynHHLL v 0.09 | hhanswer == : 1158.000000 | 2022-06-24 18:52:02.049
Chart: Replay 60X: ESU22_FUT_CME [CV][M] 1 Min #4 | Study: DynHHLL v 0.09 | llanswer == : 0.000000 | 2022-06-24 18:52:02.049
Chart: Replay 60X: ESU22_FUT_CME [CV][M] 1 Min #4 | Study: DynHHLL v 0.09 | lookback == : 5 | 2022-06-24 18:52:02.049
Chart: Replay 60X: ESU22_FUT_CME [CV][M] 1 Min #4 | Study: DynHHLL v 0.09 | sc.Index == : 0.000000 | 2022-06-24 18:52:02.049
Chart: Replay 60X: ESU22_FUT_CME [CV][M] 1 Min #4 | Study: DynHHLL v 0.09 | Study1Array[sc.Index] == : 628.000000 | 2022-06-24 18:52:02.049
Chart: Replay 60X: ESU22_FUT_CME [CV][M] 1 Min #4 | Study: DynHHLL v 0.09 | hhanswer == : 1632.500000 | 2022-06-24 18:52:05.073
Chart: Replay 60X: ESU22_FUT_CME [CV][M] 1 Min #4 | Study: DynHHLL v 0.09 | llanswer == : 0.000000 | 2022-06-24 18:52:05.073
Chart: Replay 60X: ESU22_FUT_CME [CV][M] 1 Min #4 | Study: DynHHLL v 0.09 | lookback == : 5 | 2022-06-24 18:52:05.073
Chart: Replay 60X: ESU22_FUT_CME [CV][M] 1 Min #4 | Study: DynHHLL v 0.09 | sc.Index == : 0.000000 | 2022-06-24 18:52:05.073
Chart: Replay 60X: ESU22_FUT_CME [CV][M] 1 Min #4 | Study: DynHHLL v 0.09 | Study1Array[sc.Index] == : 0.000000 | 2022-06-24 18:52:05.073
Chart: Replay 60X: ESU22_FUT_CME [CV][M] 1 Min #4 | Study: DynHHLL v 0.09 | hhanswer == : 628.000000 | 2022-06-24 18:52:05.073
Chart: Replay 60X: ESU22_FUT_CME [CV][M] 1 Min #4 | Study: DynHHLL v 0.09 | llanswer == : 0.000000 | 2022-06-24 18:52:05.073

Everything looks valid? Please help! Why is the study printing NaN in the region's scale while showing valid floating point numbers (i.e. 1632.50, 0.0, ...) in the debug log? Why does a manual "recalculate" from the menu fix it all--only after manually recalculating, the region displays the information shown in the debug log correctly--and the NaN displaying on the right scale...disappears (only to re-appear again when I modify any study parameter and hit the "apply" button)?

Thanks in advance.
Date Time Of Last Edit: 2022-06-26 00:02:32
[2022-06-25 08:02:57]
User431178 - Posts: 614
The fact that your data appears when you 'recalculate' means it is a calculation precendce problem.

1) Look at calculation precedence information here - Chart Studies: Study Calculation Precedence And Related Issues

Might be beneficial to set below in the sc.SetDefaults block (ACSIL Interface Members - Variables and Arrays: sc.CalculationPrecedence)

sc.CalculationPrecedence = LOW_PREC_LEVEL

2) Suggest looking at the - ACSIL Interface Members - Functions: sc.GetStudyArrayUsingID()
There is information relating to point 1, but also example of using the function, particularly checking to see the the array has data (GetArraySize) before processing it.


Regarding NaN, it only takes one NaN value in view to cause the scale to mess up.
Date Time Of Last Edit: 2022-06-26 10:25:13
[2022-06-25 23:57:12]
User133994 - Posts: 80
User431178,

Excellent suggestions. I remember having issues with precedence before...so I'm familiar with that. Why didn't I think of that!? Thanks a lot!!

sc.CalculationPrecedence = VERY_LOW_PREC_LEVEL


^^^ finally fixed it ^^^ (LOW wasn't enough; and yes, I did need to re-order the studies as I was referencing some that were below the one I was having issues with)

Also, I tried using GetArraySize and that kindof worked (before switching to VERY_LOW...); but again, the study only painted for live data bars not ones that were already on the chart (historical) without having to recalc manually.

Bottom line: use VERY_LOW_PREC_LEVEL and make sure your referenced studies are *above* this dynamic HH/LL study.

Thanks so much for all your help!!!

For those who want to use a *dynamically* calculated HighestHigh and LowestLow, here is the full working code [enjoy]:


/*******
input a: Input_Study1/Input_Study1Subgraph--this is the study for which you want to calculate the HH or LL
input b: Input_Lookback/Input_LookbackSubgraph--this is the study that tells you how many bars back to look
for a HH or LL; it can change based on time/period/other; For example, use the wave count: i.e. how many bars
were in the last down wave? And then use that count to determine the HH/LL; and on the next wave you use the
next bar count (which is different from prior bar count). Thus, you have a HH/LL based on wave bar counts,
not a fixed number.

output HH/LL: The HH (or LL) output won't be exactly the highest high (or lowest) of the last 5 bars, but will
vary based on the number entered for "input b".
********/

//{{{ Indicator Name: generic dynamicHHLL
SCSFExport scsf_DynamicHHLL(SCStudyInterfaceRef sc)
{

  SCSubgraphRef Subgraph_HH = sc.Subgraph[0];
  SCSubgraphRef Subgraph_LL = sc.Subgraph[1];

  SCInputRef Input_Study1 = sc.Input[0];
  SCInputRef Input_Study1Subgraph = sc.Input[1];

  SCInputRef Input_Lookback = sc.Input[4];
  SCInputRef Input_LookbackSubgraph = sc.Input[5];

  SCInputRef Input_DetailedLogging = sc.Input[8];

  // Set configuration variables
  //{{{
  if (sc.SetDefaults)
  {
    // Set the configuration and defaults
   sc.CalculationPrecedence = VERY_LOW_PREC_LEVEL;  

    sc.GraphName = "DynHHLL v 0.19";
    sc.GraphRegion = 4;
    
    // Set the Length input and default it to 30
Input_Lookback.Name = "Input Study to determine Lookback Range";
    Input_Lookback.SetStudyID(100);
    
    Input_LookbackSubgraph.Name = "Lookback Study Subgraph";
    Input_LookbackSubgraph.SetSubgraphIndex(0);

    Subgraph_HH.Name = "DynHighestHigh";
    Subgraph_HH.DrawStyle = DRAWSTYLE_LINE;
    Subgraph_HH.PrimaryColor = RGB(0,255,0);

    Subgraph_LL.Name = "DynLowestLow";
    Subgraph_LL.DrawStyle = DRAWSTYLE_LINE;
    Subgraph_LL.PrimaryColor = RGB(0,255,255);

    Input_Study1.Name = "Input Study 1";
    Input_Study1.SetStudyID(11);

    Input_Study1Subgraph.Name = "Study 1 Subgraph";
    Input_Study1Subgraph.SetSubgraphIndex(0);

    Input_DetailedLogging.Name = "Detailed Logging (for debugging)";
    Input_DetailedLogging.SetYesNo(1);

    sc.AutoLoop = 1;
    
    return;
  }
  //}}}
  
  //reset some persistent variables
  int& r_LastLookback = sc.GetPersistentInt(1);
  int& LastLogMessageIdentifier =sc.GetPersistentInt(2);
  float curHighestHigh = 0.0;
  float curLowestLow = 0.0;
  
  if (sc.IsFullRecalculation) //Is full recalculation
  {
   LastLogMessageIdentifier = 0;
   r_LastLookback = 1;
  }

  if(sc.GetBarHasClosedStatus()==BHCS_BAR_HAS_CLOSED){
   //reset on each new bar also
   LastLogMessageIdentifier = 0;
   curHighestHigh = 0.0;
   curLowestLow = 0.0;
  }

//{{{ Don't run indicator in these conditions

if(sc.GetBarHasClosedStatus()==BHCS_BAR_HAS_NOT_CLOSED)
return; //do not do any processing if the bar at our current index has not closed

//}}}

  // Get the subgraph specified with the Study 1
  // Subgraph input from the study specified with
  // the Input Study 1 input.
  SCFloatArray Study1Array;
  sc.GetStudyArrayUsingID(Input_Study1.GetStudyID(),Input_Study1Subgraph.GetSubgraphIndex(),Study1Array);

  SCFloatArray LookbackStudyArray;
  sc.GetStudyArrayUsingID(Input_Lookback.GetStudyID(),Input_LookbackSubgraph.GetSubgraphIndex(),LookbackStudyArray);


  int lookback = 5;
  SCString DebugString;

  lookback = static_cast<int>(LookbackStudyArray[sc.Index]);

  //ensure lookback is positive at all times
  if (lookback <= 0){
   lookback = 1;
   r_LastLookback = 1;
  }else if(r_LastLookback <= 0){
   lookback = 5;
   r_LastLookback = 5;
  }else{
   r_LastLookback = lookback;
  }

  if (Input_DetailedLogging.GetYesNo() && LastLogMessageIdentifier != 1)
  {
   LastLogMessageIdentifier = 1;
   DebugString.Format("lookback == : %d", lookback);
   sc.AddMessageToLog(DebugString, 0);
  }

  float hhanswer = 0.0;
  float llanswer = 0.0;

  if (Input_DetailedLogging.GetYesNo() && LastLogMessageIdentifier != 2)
  {
   LastLogMessageIdentifier = 2;
  DebugString.Format("sc.Index == : %f", sc.Index);
  sc.AddMessageToLog(DebugString, 0);

  DebugString.Format("Study1Array[sc.Index] == : %f", Study1Array[sc.Index]);
  sc.AddMessageToLog(DebugString, 0);
  }

  hhanswer =sc.GetHighest(Study1Array, lookback);
  llanswer =sc.GetLowest(Study1Array, lookback);


  if (Input_DetailedLogging.GetYesNo() && LastLogMessageIdentifier != 3)
  {
   LastLogMessageIdentifier = 3;
  DebugString.Format("hhanswer == : %f", hhanswer);
  sc.AddMessageToLog(DebugString, 0);
  DebugString.Format("llanswer == : %f", llanswer);
  sc.AddMessageToLog(DebugString, 0);
  }

  
  Subgraph_HH[sc.Index] = hhanswer;
  
  Subgraph_LL[sc.Index] = llanswer;
  
}
//}}}

Thanks again.
Date Time Of Last Edit: 2022-06-25 23:59:24

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

Login

Login Page - Create Account