public PlotCollectionSet GetData(PlotCollectionSet dataset, int nDataIdx, int nLookahead, Guid?guid = null, bool bAddToParams = false) { BbData data = GetBbData(dataset, nDataIdx, nLookahead, bAddToParams); return(new PlotCollectionSet(new List <PlotCollection>() { data.DstData })); }
public BbData GetBbData(PlotCollectionSet dataset, int nDataIdx, int nLookahead = 0, bool bAddToParams = false) { BbData data = Pre(dataset, nDataIdx); MinMax minmax = new MinMax(); for (int i = 0; i < data.SrcData.Count; i++) { Process(data, i, minmax, nLookahead, bAddToParams); } data.DstData.SetMinMax(minmax); return(data); }
/// <summary> /// Calculate the BB based on Investopedia's formula. /// </summary> /// <remarks> /// @see [Bollinger Band Definition](https://www.investopedia.com/terms/b/bollingerbands.asp) /// </remarks> /// <param name="data">Specifies the BB data from the previous cycle.</param> /// <param name="i">Specifies the current data index.</param> /// <param name="minmax">Currently, not used here.</param> /// <param name="nLookahead">Specifies the look ahead value if any.</param> /// <param name="bAddToParams">Optionally, specifies whether or not to add the BB to the parameters of the original data.</param> /// <returns>The new BB values are returned.</returns> public Tuple <long, double, double, double, double, double> Process(BbData data, int i, MinMax minmax = null, int nLookahead = 0, bool bAddToParams = false) { bool bActive = data.SrcData[i].Active; Plot plot = new Plot(data.SrcData[i].X, new float[] { 0, 0, 0 }, null, false, data.SrcData[i].Index, data.SrcData[i].Action1Active, data.SrcData[i].Action2Active); data.DstData.Add(plot, false); float fTypicalValue = (data.SrcData[i].Y_values.Length == 4) ? (data.SrcData[i].Y_values[1] + data.SrcData[i].Y_values[2] + data.SrcData[i].Y_values[3]) / 3 : data.SrcData[i].Y; if (data.SrcData[i].Y_values.Length == 4 && m_target != TARGET.DEFAULT) { if (m_target == TARGET.BAR) { float fVal = (data.SrcData[i].Y_values[0] - data.SrcData[i].Y); m_caValExt.Add(fVal, null, true); } else if (m_target == TARGET.RANGE) { float fVal = (data.SrcData[i].Y_values[1] - data.SrcData[i].Y_values[2]); m_caValExt.Add(fVal, null, true); } } if (m_caVal.Add(fTypicalValue, null, false)) { data.Ave = (float)m_caVal.Average; float fStdevTp = (float)m_caVal.StdDev; if (m_target != TARGET.DEFAULT) { fStdevTp = (float)m_caValExt.StdDev; } double dfStdDvTp = (m_dfStdDev * fStdevTp); data.BbAbove = data.Ave + dfStdDvTp; data.BbBelow = data.Ave - dfStdDvTp; plot.SetYValues(new float[] { (float)data.BbBelow, (float)data.Ave, (float)data.BbAbove }, true); double dfAboveBelow = data.BbAbove - data.BbBelow; data.BbPctb = 0; if (dfAboveBelow != 0) { data.BbPctb = (data.SrcData[i].Y - data.BbBelow) / dfAboveBelow; } data.BbWid = 0; if (data.Ave != 0) { data.BbWid = dfAboveBelow / data.Ave; } if (bAddToParams && bActive) { data.SrcData[i].SetParameter(data.DstData.Name + " Below", data.BbBelow); data.SrcData[i].SetParameter(data.DstData.Name + " Ave", data.Ave); data.SrcData[i].SetParameter(data.DstData.Name + " Above", data.BbAbove); data.SrcData[i].SetParameter(data.DstData.Name + " %b", data.BbPctb); data.SrcData[i].SetParameter(data.DstData.Name + " BandWidth", data.BbWid); } if (minmax != null) { minmax.Add(data.BbBelow); minmax.Add(data.Ave); minmax.Add(data.BbAbove); } } data.Count++; return(new Tuple <long, double, double, double, double, double>((long)data.SrcData[i].X, data.BbBelow, data.Ave, data.BbAbove, data.BbPctb, data.BbWid)); }