The documentation states that:
"A Series<T> is a special generic type of data structure that can be constructed with any chosen data type and holds a series of values equal to the same number of elements as bars in a chart. If you have 200 bars loaded in your chart with a moving average plotted, the moving average itself holds a Series<double> object with 200 historical values of data, one for each bar. Series<double> objects can be used as input data for all indicator methods. The Series<T> class implements the ISeries<T> interface."
I could not find an example of storing objects, accesing getters and setters and accessing object methods by bar index, so put the following code together to confirm it compiles and runs as expected. It seems to work!
Is this supported?
Are the examples of how to do this on the forum?
namespace NinjaTrader.NinjaScript.Indicators { public class ObjectByBar : Indicator { private class Zone { private double highZone = 0.0; private double lowZone = 0.0; private string txt = string.Empty; //constructor public Zone(double l, double h, string t) { this.lowZone = l; this.highZone = h; this.txt = t; } public double highadjusted() { return highZone/2.0; } //properties public double HighZone { get { return highZone; } set { highZone = value; } } public double LowZone { get { return lowZone; } set { lowZone = value; } } public string Txt { get { return txt; } set { txt = value; } } } //declare Series<t> of Zone objects private Series<Zone> zones; private Series<double> zonesHigh; protected override void OnStateChange() { if (State == State.SetDefaults) { Description = @"Demonstration to show how to store an arbitary object aligned by each bar"; Name = "ObjectByBar"; Calculate = Calculate.OnBarClose; IsOverlay = false; DisplayInDataBox = true; DrawOnPricePanel = true; DrawHorizontalGridLines = true; DrawVerticalGridLines = true; PaintPriceMarkers = true; ScaleJustification = NinjaTrader.Gui.Chart.ScaleJustification.Right; //Disable this property if your indicator requires custom values that cumulate with each new market data event. //See Help Guide for additional information. IsSuspendedWhileInactive = true; AddPlot(new Stroke(Brushes.Blue, 1), PlotStyle.Line, "SMAPlot"); AddPlot(new Stroke(Brushes.Red, 1), PlotStyle.Line, "High"); } else if (State == State.DataLoaded) { //instatiate Series zones = new Series<Zone>(this); zonesHigh = new Series<double>(this); } } protected override void OnBarUpdate() { //create Zone object and store in zones[0] zones[0] = new Zone(Low[0] * 2.0, High[0] * 2.0, " This bar num: " + CurrentBar.ToString()); //demonstrate that getters / setters work as expected if (CurrentBar > 1) { Print("previous bar data: HighZone[1] " + zones[1].HighZone + " Current bar HighZone " + zones[0].HighZone + zones[0].Txt); //update the Txt zones[0].Txt = " demos that setter works! "; //show updated txt field Print("previous bar data: HighZone[1] " + zones[1].HighZone + " Current bar HighZone " + zones[0].HighZone + zones[0].Txt); } //store zones HighZone in Series<double> which can be then passed into any indicator. zonesHigh[0] = zones[0].HighZone; Values[0][0] = SMA(zonesHigh,10)[0] / 2.0; //excercise Zone method. Values[1][0] = zones[0].highadjusted(); } } }
Comment