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