Login Page - Create Account

Support Board


Date/Time: Thu, 06 Mar 2025 12:51:37 +0000



[Programming Help] - Study only Accurate/Visible after Full Calculation ?

View Count: 616

[2022-01-29 09:09:58]
SelimEker - Posts: 13
Hi everyone !

I'm a newbie, as it is just this week that I started working with SC. I have built a Custom Study that is supposed to highlight certain legs bar highs (or lows) after a Swingpoint. My study is accurate whenever i do a Recalculation, but if i run the (Standard) Replay it starts highlighting wrong parts. As for the other replay types or using "live" data, it doesn't do anything.

I think the issue is how I get the data "into" the study but I cant figure how to make it work. (I have tried sc.GetChartBaseData but can't make it work aswell)...

Can you point what I am doing wrong ?

I would greatly appreciate it.

Here is the code:

// This must be exactly "sierrachart.h" to ensure you are referencing the correct header file.
#include "sierrachart.h"

// Change the text within the quote marks to what you want to name your group of custom studies.
SCDLLName("DPB")


int DownLegCounter = 1;
int UpLegCounter = 1;


float SwingLatestHigh = 0;
float SwingLatestLow = 99999;

float LowestLongPrice = 0;
float HighestShortPrice = 0;



SCSFExport scsf_DPB(SCStudyInterfaceRef sc)
{

  // XXXXXXXXXXXXXXXXXXXXX sc.GraphName = "DPB"; XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ---> Removed since i called the function twice

  SCSubgraphRef Subgraph_LONG = sc.Subgraph[0];
  SCSubgraphRef Subgraph_SHORT = sc.Subgraph[1];



  

  if (sc.SetDefaults)
  {
    sc.GraphName = "Double Pull Back";
    sc.StudyDescription = "Double Pull Back";
    sc.GraphRegion = 0;

    Subgraph_LONG.Name = "LONG";
    Subgraph_LONG.DrawStyle = DRAWSTYLE_STAIR_STEP;
    Subgraph_LONG.PrimaryColor = RGB(0, 64, 128);
    Subgraph_LONG.LineWidth = 2;
    Subgraph_LONG.DrawZeros = false;

    Subgraph_SHORT.Name = "SHORT";
    Subgraph_SHORT.DrawStyle = DRAWSTYLE_STAIR_STEP;
    Subgraph_SHORT.PrimaryColor = RGB(128, 0, 0);
    Subgraph_SHORT.LineWidth = 2;
    Subgraph_SHORT.DrawZeros = false;


    sc.AutoLoop = 1;

    return;
  }



    float high = sc.High[sc.Index];
    float highOld = sc.High[sc.Index - 1];
    float highOld2 = sc.High[sc.Index - 2];
    float highOld3 = sc.High[sc.Index - 3];
    float highOld4 = sc.High[sc.Index - 4];


    float low = sc.Low[sc.Index];
    float lowOld = sc.Low[sc.Index - 1];
    float lowOld2 = sc.Low[sc.Index - 2];
    float lowOld3 = sc.Low[sc.Index - 3];
    float lowOld4 = sc.Low[sc.Index - 4];


And to spare you with all the conditions:


if (highOld > high && highOld > highOld2 && SwingLatestHigh >= highOld) // Clear Peaks Lower than Last Swing -> New Leg
    {
      DownLegCounter = DownLegCounter + 1;
      SwingLatestHigh = highOld;
    }


//Drawing of Highlighted Highs

if (high < highOld && DownLegCounter == 2)
    {
      Subgraph_LONG[sc.Index] = high;
      LowestLongPrice = high;
    }
    else if (high == LowestLongPrice && DownLegCounter == 2)
    {
      Subgraph_LONG[sc.Index] = high;
    }
    else
    {
      Subgraph_LONG[sc.Index] = 0;
    }


Date Time Of Last Edit: 2022-01-30 09:53:50
[2022-01-30 06:09:53]
1+1=10 - Posts: 270
You have to either tell SC to loop through the chart bars for you or do it yourself.

For the former, see sc.Autoloop =1; detailed here:
Working with ACSIL Arrays and Understanding Looping: Automatic Looping/Iterating

For looping yourself you should probably read this whole thing:
Working with ACSIL Arrays and Understanding Looping
[2022-01-30 08:19:39]
SelimEker - Posts: 13
Thank you for the answer. I already went through this reading before, and after reading it again I sadly do not find the solution. Im so sorry for being annoying/needy...

As you can see AutoLoop was already stated as =1 in the code above, I really want to keep away from the pain of doing manual looping... especially when AutoLoop should work just fine.

I saw that in the first link the example provided with a different way of getting the Highs and Lows of the bar (with sc.BaseData[SC_HIGH][sc.Index]) which i tried but had no impact.



UPDATE: On my quest of debugging I activated DrawZero to true, and when replaying the chart my study is drawing a constant line at zero... then when the replay stops the values become correct. Could it be the float temporary variable that are not updating ? Or is it linked to the global variables ?

I tried replacing the global variables by persistent ones --> Same result.
Date Time Of Last Edit: 2022-01-30 14:15:26
[2022-01-30 14:59:49]
1+1=10 - Posts: 270
Sorry I missed that!

Looking again I think that there’s a bug here:
if (highOld > high && highOld > highOld2 && SwingLatestHigh >= highOld) // Clear Peaks Lower than Last Swing -> New Leg

“SwingLatestHigh >= highOld” starts false and stays false, I think.
[2022-01-30 15:02:43]
1+1=10 - Posts: 270
Also, if you ever want to apply the study to multiple charts then it won’t work because the global variables will be shared by every study.

It is best practice to use persistent variables:
ACSIL Interface Members - Functions: Persistent Variable Functions
[2022-01-30 15:27:06]
SelimEker - Posts: 13
When thinking about sparing you with useless, here i am giving you the full bean. As you mention the first if doesnt go through but there are other to catch up.

However i think i found the problem. Since this code is running multiples time per bar the DownLegCounter is incrementing tons of time.
While coding my brain thought it would run only once per bar.

As for the why it works when doing full recalculation is because during that the code is run only once per bar !!!!!! DAMN i spent two days, i think i got it now.

Hopefully i come back and confirm my theory once i find a way to make it work :D

First try will be with: sc.GetBarHasClosedStatus() == BHCS_BAR_HAS_CLOSED hoping the indexes are not being shifted.



if ( (highOld > high) && (highOld > highOld2) && (SwingLatestHigh >= highOld) ) // Clear Peaks Lower than Last Swing -> New Leg
    {
      DownLegCounter = DownLegCounter + 1;
      SwingLatestHigh = highOld;
    }
    else if ( (highOld > high) && (highOld > highOld2) && (SwingLatestHigh < highOld) ) // Clear Peaks Higher than last Swing -> Reset Leg
    {
      DownLegCounter = 1;
      SwingLatestHigh = highOld;
    }
    else if( (highOld > high) && (highOld == highOld2) && (highOld3 < highOld2) && (SwingLatestHigh >= highOld) ) // Double Peak -> New Leg
    {
      DownLegCounter = DownLegCounter + 1;
      SwingLatestHigh = highOld;
    }
    else if( (highOld > high) && (highOld == highOld2) && (highOld3 < highOld2) && (SwingLatestHigh < highOld) ) // Double Peak -> Reset
    {
      DownLegCounter = 1;
      SwingLatestHigh = highOld;
    }
    else if ( (highOld > high) && (highOld == highOld2) && (highOld2 == highOld3) && (highOld4 < highOld3) && (SwingLatestHigh >= highOld) ) // Triple Peak -> New Leg
    {
      DownLegCounter = DownLegCounter + 1;
      SwingLatestHigh = highOld;
    }
    else if ( (highOld > high) && (highOld == highOld2) && (highOld2 == highOld3) && (highOld4 < highOld3) && (SwingLatestHigh < highOld) ) // Triple Peak -> Reset
    {
      DownLegCounter = 1;
      SwingLatestHigh = highOld;
    }

    


    // If high(i) < high(i-1) AND DownLegCounter = 2


    if ( (high < highOld) && (DownLegCounter == 2) )
    {
      Subgraph_LONG[sc.Index] = high;
      LowestLongPrice = high;
    }
    else if ( (high == LowestLongPrice) && (DownLegCounter == 2) )
    {
      Subgraph_LONG[sc.Index] = high;
    }
    else
    {
      Subgraph_LONG[sc.Index] = 0;



    }

[2022-01-30 15:34:55]
SelimEker - Posts: 13
Alright good news it is fixed !
[2022-01-30 15:46:33]
1+1=10 - Posts: 270
Oh yeah, that makes sense. Glad you figured it out!

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

Login

Login Page - Create Account