I seem to have found a bug. This bug seems to occur when you have an indicator that uses more than one security to calculate its value.
I have an indicator called Spread and it basically calculates the spread between two contracts...pretty straight forward, Closes[0][0] - Closes[1][0] is pretty much the essence of it.
When I use this indicator in a strategy, it works - i.e. I Add() it in initialize, and displays correctly. However, as soon as I do any calculation involving it, the spread value becomes completely out of whack. For example, in OnBarUpdate, let's say I check for this:
if (SMA(mySpread,2)[0] > 10) { // do something }
Here is my code for the strategy:
namespace NinjaTrader.Strategy { /// <summary> /// Simple moving average cross over strategy. /// </summary> [Description("Simple moving average cross over strategy.")] public class BasicTester : Strategy { #region Variables private Spread bobby; #endregion /// <summary> /// This method is used to configure the strategy and is called once before any strategy method is called. /// </summary> protected override void Initialize() { CalculateOnBarClose = true; bobby = Spread("6C 09-10", 100, 100); Add(bobby); } /// <summary> /// Called on each bar update event (incoming tick). /// </summary> protected override void OnBarUpdate() { if (SMA(Spread("6C 09-10",100,100),2)[0] > 100) { Print("BOb is big!"); } Print("From strategy: " + bobby[0]); Print("From strategy recalc: " + Spread("6C 09-10", 100, 100)[0]); Print("Public var from strat: " + bobby.MySpread[0]); } #region Properties /// <summary> /// </summary> /// [Description("Period for fast MA")] /// [GridCategory("Parameters")] /// public int X /// { /// get { return x; } /// set { x = Math.Max(1, value); } ///} #endregion } }
Any ideas?
Here is the spread code if needed:
/// <summary> /// Spread between two instruments given a specific spread ratio /// </summary> [Description("Spread between two instruments given a specific spread ratio")] public class Spread : Indicator { #region Variables // Variables private int quotedQuantity = 1; // Default setting for QuotedQuantity private int hedgeQuantity = 1; // Default setting for HedgeQuantity private string hedgeInstrument = @""; // Default setting for HedgeInstrument private double spreadRough; private DataSeries mySpread; private int barValue; #endregion /// <summary> /// This method is used to configure the indicator and is called once before any bar data is loaded. /// </summary> protected override void Initialize() { Add(new Plot(Color.Gray, PlotStyle.Line, "Spread")); barValue = Math.Max(1, base.BarsPeriod.Value); Add(hedgeInstrument, BarsPeriod.Id, barValue); mySpread = new DataSeries(this); } /// <summary> /// Called on each bar update event (incoming tick) /// </summary> protected override void OnBarUpdate() { // NT Crashes if these conditions aren't in place... if (hedgeInstrument == "" || hedgeInstrument == Instrument.FullName) { Print("instrument error"); return; } if (CurrentBars[0] < 1) { Print("CurrentBars[0]: " + CurrentBars[0] + " " + Time[0] + " " + CurrentBar); return; } if (CurrentBars[1] < 1) { Print("CurrentBars[1]: " + CurrentBars[1] + " " + Time[0] + " " + CurrentBar); return; } //Calculate spread try { spreadRough = (Closes[0][0]*quotedQuantity)-(Closes[1][0]*hedgeQuantity); mySpread.Set(Math.Round(spreadRough, 4)); Print("CloseBase: " + Closes[0][0] + " CloseHedge: " + Closes[1][0] + "Spread: " + spreadRough); Value.Set(Math.Round(spreadRough, 4)); } catch (Exception e) { Print(Time[0] + " Indicator SpreadZScore on " + Instrument.FullName+ " Error: mySpread.Set" + " " + e.ToString()); } } #region Properties [Browsable(false)] // this line prevents the data series from being displayed in the indicator properties dialog, do not remove [XmlIgnore()] // this line ensures that the indicator can be saved/recovered as part of a chart template, do not remove public DataSeries MySpread { get { return mySpread; } } [Description("Number of Contracts for Base Series")] [GridCategory("Spread Parameters")] public int QuotedQuantity { get { return quotedQuantity; } set { quotedQuantity = Math.Max(1, value); } } [Description("Numbers of Contracts for Hedge Instrument")] [GridCategory("Spread Parameters")] public int HedgeQuantity { get { return hedgeQuantity; } set { hedgeQuantity = Math.Max(1, value); } } [Description("Hedge Instrument Symbol - ex. ES 09-10")] [GridCategory("Spread Parameters")] public string HedgeInstrument { get { return hedgeInstrument; } set { hedgeInstrument = value.ToUpper(); } } #endregion }
Comment