//original study by QuantAlgo #include "sierrachart.h" SCDLLName("APZ Oscillator") SCSFExport scsf_APZOscillator(SCStudyInterfaceRef sc) { SCSubgraphRef TrendPlot = sc.Subgraph[0]; SCInputRef Length = sc.Input[0]; SCInputRef Threshold = sc.Input[1]; SCInputRef Smooth = sc.Input[2]; if (sc.SetDefaults) { sc.GraphName = "APZ Oscillator"; sc.AutoLoop = 1; sc.GraphRegion = 1; sc.ValueFormat = VALUEFORMAT_INHERITED; TrendPlot.Name = "Trend"; TrendPlot.DrawStyle = DRAWSTYLE_LINE; TrendPlot.LineWidth = 2; TrendPlot.PrimaryColor = RGB(0, 255, 170); TrendPlot.SecondaryColor = RGB(255, 0, 0); TrendPlot.SecondaryColorUsed = 1; TrendPlot.DrawZeros = false; Length.Name = "APZ Length"; Length.SetInt(21); Length.SetIntLimits(1, MAX_STUDY_LENGTH); Threshold.Name = "Threshold"; Threshold.SetFloat(2.0f); Threshold.SetFloatLimits(0.1f, 100.0f); Smooth.Name = "Smoothing"; Smooth.SetInt(5); Smooth.SetIntLimits(1, MAX_STUDY_LENGTH); return; } const SCFloatArrayRef Close = sc.Close; const SCFloatArrayRef High = sc.High; const SCFloatArrayRef Low = sc.Low; const int index = sc.Index; SCFloatArrayRef Typical = sc.Subgraph[0].Arrays[0]; SCFloatArrayRef AbsDelta = sc.Subgraph[0].Arrays[1]; SCFloatArrayRef Volatility = sc.Subgraph[0].Arrays[2]; SCFloatArrayRef SmoothedTypical = sc.Subgraph[0].Arrays[3]; SCFloatArrayRef UpperBand = sc.Subgraph[0].Arrays[4]; SCFloatArrayRef LowerBand = sc.Subgraph[0].Arrays[5]; SCFloatArrayRef PrevTrend = sc.Subgraph[0].Arrays[6]; //typical price Typical[index] = (High[index] + Low[index] + Close[index]) / 3.0f; //vol AbsDelta[index] = index > 0 ? fabsf(Typical[index] - Typical[index - 1]) : 0.0f; //abs delta sc.ExponentialMovAvg(AbsDelta, Volatility, Length.GetInt()); //ema sc.ExponentialMovAvg(Typical, SmoothedTypical, Smooth.GetInt()); //bands float threshold = Threshold.GetFloat(); UpperBand[index] = SmoothedTypical[index] + threshold * Volatility[index]; LowerBand[index] = SmoothedTypical[index] - threshold * Volatility[index]; //trend float currentTrend = 0.0f; if (index > 0) { if (Typical[index] > UpperBand[index - 1]) currentTrend = 1.0f; else if (Typical[index] < LowerBand[index - 1]) currentTrend = -1.0f; else currentTrend = PrevTrend[index - 1]; } PrevTrend[index] = currentTrend; TrendPlot[index] = currentTrend; //color TrendPlot.DataColor[index] = (currentTrend > 0) ? TrendPlot.PrimaryColor : TrendPlot.SecondaryColor; }