Support Board
Date/Time: Tue, 15 Apr 2025 13:01:11 +0000
Post From: sc.GetStudyIDByIndex / sc.GetStudyIDByName always return 0
[2025-04-12 14:56:04] |
Richard Chinn - Posts: 33 |
Thanks for your help and the code but it didn't work for me as it was. Just to make sure it isn't something on my machine I downloaded the current version of Sierra Chart onto a new machine. I used the Analysis->New/Open Custom Study Files and copied the code in and saved it. I had to add two lines at the top which are: #include "sierrachart.h"
SCDLLName("StudyInformation"); I used Analysis->Build Custom Studies DLL and compiled the .dll When it executes, I get no messages that anything is happening at all. So this is how I understand the study after the SetDefaults block: 1. The first guard only allows this study to run on the very first index -> Not an issue if (sc.UpdateStartIndex != 0) return; 2. Assign the sc.Input values to chartNumber and identifier -> Also not an issue 3. The second guard is catching an issue. The code can never get past this guard because of: sc.Input[0].SetChartNumber(0); in the SetDefaults block, which is then assigned to chartNumber here: const auto chartNumber = sc.Input[0].GetChartNumber(); So chartNumber is assigned zero. When the guard checks it, it fails because chartNumber is zero: if (chartNumber == 0 || identifier <= 0)
return; 4. All I had to do was change: sc.Input[0].SetChartNumber(0); TO sc.Input[0].SetChartNumber(1); to get the study to work. The revised code returns the right values as you stated but: - It takes two study execution cycles so the while(true) loop runs at least twice. - The issue is not readily apparent without a counter. If we add one more study and a counter the issue is easier to see. I used the study you supplied and: - Modified it to add an additional study. - Added an execCounter to show how many times the study runs while sc.Index is zero. (3 times on my machine) - Provided the log below, its short. You can see in the study I manually add two studies to the chart before the while(true) loop. That should mean all three studies are available to the while(true) loop each time the loop is entered. On the first Study execution (execCounter == 1), the while(true) loop only displays the "Study Information" study (correct but should have displayed all 3) On the second execution (execCounter == 2), the while(true) loop only displays the first and second study (As above, the values are correct but it should have displayed all 3) It's not until the third execution (execCounter == 3) that all three studies are displayed and at this point, they are all displayed correctly. In my personal study I assume the information is available once the studies are added, I don't perform multiple loops to obtain the information because according to the documentation, sc.AddStudyToChart returns the unique sc.StudyGraphInstanceID, which is exactly the value I am trying to get. I do this in my code: const auto result = sc.AddStudyToChart(addStudy), then use the "Result", expecting it to be correct. If I understand what is happening correctly... - The real issue is NOT: sc.GetStudyIDByIndex (which does show the correct values, proved in the while loop) - The real issue is: The return value of sc.AddStudyToChart (I added two studies, ATR and EMA, so the "Result" should be 2 and 3 respectively because "Study Information" is 1, the first study instance on the chart) You can see in the log output, that Result == 1 each time the study executes on every study, (this is where I think the issue is). - The Results provided by sc.AddStudyToChart are not used in the while(true) loop. - We are making the evaluation this way: const auto id = sc.GetStudyIDByIndex(chartNumber, studyIndex++); - The while(true) loop is providing the correct values but only 1 study at a time. - The loop has to execute (not iterate) three times to provide the correct values for all three studies. - It is correctly displaying study values because we are not evaluating the return values of sc.AddStudyToChart. LOG: 2025-04-12 12:51:14.036 | Loading DLL: C:\SierraChart\Data\GetStudyInformation.dll (GetStudyInformation_64.dll). Handle: 66000000 2025-04-12 12:51:22.876 | Chart: Replay 1.00X: ESM25-CME[M] 1 Min #1 | Study: Study Information | EXECUTION COUNTER: sc.Index == 0 | execCounter == 1 2025-04-12 12:51:22.876 | Chart: Replay 1.00X: ESM25-CME[M] 1 Min #1 | Study: Study Information | ATR: Result == 1 | Study with internal ID 19 added to chart number 1 2025-04-12 12:51:22.876 | Chart: Replay 1.00X: ESM25-CME[M] 1 Min #1 | Study: Study Information | EMA: Result == 1 | Study with internal ID 27 added to chart number 1 2025-04-12 12:51:22.876 | Chart: Replay 1.00X: ESM25-CME[M] 1 Min #1 | Study: Study Information | while(true): Study ID: 1, Name: Study Information 2025-04-12 12:51:22.912 | Chart: Replay 1.00X: ESM25-CME[M] 1 Min #1 | Study: Study Information | EXECUTION COUNTER: sc.Index == 0 | execCounter == 2 2025-04-12 12:51:22.912 | Chart: Replay 1.00X: ESM25-CME[M] 1 Min #1 | Study: Study Information | ATR: Result == 1 | Study with internal ID 19 added to chart number 1 2025-04-12 12:51:22.912 | Chart: Replay 1.00X: ESM25-CME[M] 1 Min #1 | Study: Study Information | EMA: Result == 1 | Study with internal ID 27 added to chart number 1 2025-04-12 12:51:22.912 | Chart: Replay 1.00X: ESM25-CME[M] 1 Min #1 | Study: Study Information | while(true): Study ID: 1, Name: Study Information 2025-04-12 12:51:22.912 | Chart: Replay 1.00X: ESM25-CME[M] 1 Min #1 | Study: Study Information | while(true): Study ID: 2, Name: Average True Range 2025-04-12 12:51:22.917 | Chart: Replay 1.00X: ESM25-CME[M] 1 Min #1 | Study: Study Information | EXECUTION COUNTER: sc.Index == 0 | execCounter == 3 2025-04-12 12:51:22.917 | Chart: Replay 1.00X: ESM25-CME[M] 1 Min #1 | Study: Study Information | ATR: Result == 1 | Study with internal ID 19 added to chart number 1 2025-04-12 12:51:22.917 | Chart: Replay 1.00X: ESM25-CME[M] 1 Min #1 | Study: Study Information | EMA: Result == 1 | Study with internal ID 27 added to chart number 1 2025-04-12 12:51:22.917 | Chart: Replay 1.00X: ESM25-CME[M] 1 Min #1 | Study: Study Information | while(true): Study ID: 1, Name: Study Information 2025-04-12 12:51:22.917 | Chart: Replay 1.00X: ESM25-CME[M] 1 Min #1 | Study: Study Information | while(true): Study ID: 2, Name: Average True Range 2025-04-12 12:51:22.917 | Chart: Replay 1.00X: ESM25-CME[M] 1 Min #1 | Study: Study Information | while(true): Study ID: 3, Name: Moving Average - Exponential And Here is the revised study you sent me: #include "sierrachart.h" SCDLLName("StudyInformation"); SCSFExport scsf_GetStudyInformation(SCStudyInterfaceRef sc) { if (sc.SetDefaults) { sc.GraphName = "Study Information"; sc.GraphRegion = 0; sc.AutoLoop = 0; sc.ValueFormat = VALUEFORMAT_INHERITED; sc.ScaleRangeType = SCALE_SAMEASREGION; sc.GlobalDisplayStudySubgraphsNameAndValue = 0; sc.DisplayStudyInputValues = 0; sc.HideDLLAndFunctionNames = 1; sc.Input[0].Name = "Chart Number"; sc.Input[0].SetChartNumber(1); // REVISED FROM 0 TO 1 sc.Input[1].Name = "Study to Add Internal ID"; sc.Input[1].SetInt(19); // ATR sc.Input[2].Name = "Exponential Moving Avaerage"; sc.Input[2].SetInt(27); // EMA return; } if (sc.UpdateStartIndex != 0) { return; } // Add an execution counter //------------------------- static int execCounter = 0; // This counts how many times the study executes while sc.Index == 0 sc.AddMessageToLog(SCString().Format("EXECUTION COUNTER: sc.Index == %d | execCounter == %d", sc.Index, ++execCounter), 0); const auto chartNumber = sc.Input[0].GetChartNumber(); // Add an ATR study to the chart //------------------------------ const auto atrIdentifier = sc.Input[1].GetInt(); auto atrStudy = n_ACSIL::s_AddStudy{}; atrStudy.ChartNumber = chartNumber; atrStudy.StudyID = atrIdentifier; const auto atrResult = sc.AddStudyToChart(atrStudy); if(chartNumber == 0 || atrIdentifier <= 0) return; if (atrResult != 0) sc.AddMessageToLog(SCString().Format("ATR: Result == %d | Study with internal ID %d added to chart number %d" , atrResult , atrIdentifier , chartNumber), 0); // Add an EMA study to the chart //------------------------------ const auto emaIdentifier = sc.Input[2].GetInt(); auto emaStudy = n_ACSIL::s_AddStudy{}; emaStudy.ChartNumber = chartNumber; emaStudy.StudyID = emaIdentifier; const auto emaResult = sc.AddStudyToChart(emaStudy); if(chartNumber == 0 || emaIdentifier <= 0) return; if (emaResult != 0) sc.AddMessageToLog(SCString().Format("EMA: Result == %d | Study with internal ID %d added to chart number %d" , emaResult , emaIdentifier , chartNumber), 0); // Display Study Data In Loop //--------------------------- auto studyIndex{ 1 }; while (true) { const auto id = sc.GetStudyIDByIndex(chartNumber, studyIndex++); if (id <= 0) break; const auto studyName = sc.GetStudyNameFromChart(chartNumber, id); sc.AddMessageToLog(SCString().Format("while(true): Study ID: %d, Name: %s" , id , studyName.GetChars()), 0); } } |