Support Board
Date/Time: Sun, 12 Jan 2025 12:44:23 +0000
Post From: Study subgraph returns -nan when referencing [sc.Index - 1]
[2017-02-15 17:29:21] |
reticent67 - Posts: 4 |
I'm trying to recreate Ehlers Stochastic, which is basically a stochastic of his Roofing Filter (located in the user contributed source code). The final calculation of the Roofing Filter is this Filter[sc.Index] = c1 * (HP[sc.Index] + HP[sc.Index - 1]) / 2 + c2 * Filter[sc.Index - 1] + c3 * Filter[sc.Index - 2];
This works perfectly fine. But when I take the stochastic of Filter and apply the same calculation, the result is -nan. float highestFilter = sc.GetHighest(Filter, Length.GetInt());
float lowestFilter = sc.GetLowest(Filter, Length.GetInt()); Stoch[sc.Index] = (Filter[sc.Index] - lowestFilter) / (highestFilter - lowestFilter); //same as Roofing Filter above - which works ES[sc.Index] = c1 * (Stoch[sc.Index] + Stoch[sc.Index - 1]) / 2 + c2 * ES[sc.Index - 1] + c3 * ES[sc.Index - 2]; I've debugged the code and all the formulas calculate as expected. However, as soon as I try to reference ES[sc.Index -1], the result is -nan. Referencing the previous values of the other arrays works perfectly, but not the ES subgraph. I've never run into this issue before. What is it I'm missing? Here is the entire source code for reference: // The top of every source code file must include this line
#include <Windows.h> #include <math.h> #include <iterator> #include "sierrachart.h" SCDLLName("Ehler's Stochastic") SCSFExport scsf_EhlersStochastic(SCStudyInterfaceRef sc) { // Reference the Plots and the inputs SCSubgraphRef ES = sc.Subgraph[0]; SCSubgraphRef OB = sc.Subgraph[1]; SCSubgraphRef OS = sc.Subgraph[2]; SCInputRef Price = sc.Input[0]; SCInputRef Length = sc.Input[1]; SCInputRef Bars = sc.Input[2]; SCInputRef Cutoff = sc.Input[3]; //Define arrays for intermediate caclulations SCFloatArrayRef HP = ES.Arrays[0]; SCFloatArrayRef Filter = ES.Arrays[1]; SCFloatArrayRef Stoch = ES.Arrays[2]; if (sc.SetDefaults) { // Section 1 - Set the configuration variables and defaults sc.GraphName = "Ehlers Stochastic"; // Name in study overview sc.StudyDescription = "From Predictive Indicators for Effective Trading Strategies By John Ehlers"; sc.GraphRegion = 1; // Set the Chart Region to draw the graph in. Region 0 is the main price graph sc.FreeDLL = 1; sc.AutoLoop = 1; //Auto looping is enabled. sc.ValueFormat = 2; sc.ScaleRangeType = SCALE_AUTO; // Define plots and inputs ES.Name = "EhlersStochastic"; ES.DrawStyle = DRAWSTYLE_LINE; ES.PrimaryColor = RGB(255, 0, 255); OB.Name = "Overbought"; OB.DrawStyle = DRAWSTYLE_DASH; OB.PrimaryColor = RGB(128, 128, 128); OS.Name = "Oversold"; OS.DrawStyle = DRAWSTYLE_DASH; OS.PrimaryColor = RGB(128, 128, 128); Price.Name = "Price Type"; Price.SetInputDataIndex(SC_LAST); Length.Name = "Period"; Length.SetInt(20); Length.SetIntLimits(1, MAX_STUDY_LENGTH); Cutoff.Name = "Cutoff Period"; Cutoff.SetInt(10); Cutoff.SetIntLimits(1, MAX_STUDY_LENGTH); Bars.Name = "Highpass filter length"; Bars.SetInt(48); Bars.SetIntLimits(1, MAX_STUDY_LENGTH); return; } OB[sc.Index] = .8; OS[sc.Index] = .2; //First calculate the Highpass Filter float alpha1 = (cos(sqrt(2) * 3.14159f / Bars.GetInt()) + sin(sqrt(2) * 3.14159f / Bars.GetInt()) - 1) / cos(sqrt(2) * 3.14159f / Bars.GetInt()); HP[sc.Index] = (1 - alpha1 / 2) * (1 - alpha1 / 2) * (sc.BaseDataIn[Price.GetInputDataIndex()][sc.Index] - 2 * sc.BaseDataIn[Price.GetInputDataIndex()][sc.Index - 1] + sc.BaseDataIn[Price.GetInputDataIndex()][sc.Index - 2]) + 2 * (1 - alpha1) * HP[sc.Index - 1] - (1 - alpha1) * (1 - alpha1) * HP[sc.Index - 2]; //Smooth the HighPass With Super Smoother float a1, c1, c2, c3; a1 = exp(-3.14159f * sqrt(2) / Cutoff.GetInt()); c2 = 2 * a1 * cos(sqrt(2) * 3.14159f / Cutoff.GetInt()); c3 = -a1 * a1; c1 = 1 - c2 - c3; Filter[sc.Index] = c1 * (HP[sc.Index] + HP[sc.Index - 1]) / 2 + c2 * Filter[sc.Index - 1] + c3 * Filter[sc.Index - 2]; //Calculate and plot the Stochastic float highestFilter = sc.GetHighest(Filter, Length.GetInt()); float lowestFilter = sc.GetLowest(Filter, Length.GetInt()); Stoch[sc.Index] = (Filter[sc.Index] - lowestFilter) / (highestFilter - lowestFilter); ES[sc.Index] = c1 * (Stoch[sc.Index] + Stoch[sc.Index - 1]) / 2 + c2 * ES[sc.Index - 1] + c3 * ES[sc.Index - 2]; } |