I'm trying to modify the indicator created by AdamP and kdoren (?), located here, which charts futures calendar spreads (2 contracts months/legs), so that it can chart butterfly (3 legs) and condor (4 legs) as well. Here is the source code:
//
// Copyright (C) 2006, NinjaTrader LLC <www.ninjatrader.com>.
// NinjaTrader reserves the right to modify or overwrite this NinjaScript component with each release.
//
#region Using declarations
using System;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.ComponentModel;
using System.Xml.Serialization;
using NinjaTrader.Data;
using NinjaTrader.Gui.Chart;
#endregion
// This namespace holds all indicators and is required. Do not change it.
namespace NinjaTrader.Indicator
{
/// <summary>
/// SpreadCandlesticks
/// </summary>
[Description("SpreadCandlesticks")]
public class SpreadCandlesticks : Indicator
{
#region Variables
private string symbol2 = ""; // Symbol for Instrument2 (full name, i.e. "ES 03-10" for futures)
private double qty1=1; // Default Quantity for Instrument1
private double qty2=-1; // Default Quantity for Instrument2
private bool supportedBarsPeriodType = false;
private Color barColorDown = Color.Red;
private Color barColorUp = Color.Lime;
private SolidBrush brushDown = null;
private SolidBrush brushUp = null;
private Color shadowColor = Color.Black;
private Pen shadowPen = null;
private int shadowWidth = 1;
#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, "SpreadOpen"));
Add(new Plot(Color.Gray, PlotStyle.Line, "SpreadHigh"));
Add(new Plot(Color.Gray, PlotStyle.Line, "SpreadLow"));
Add(new Plot(Color.Gray, PlotStyle.Line, "SpreadClose"));
PaintPriceMarkers = false;
CalculateOnBarClose = false;
PlotsConfigurable = false;
Overlay = false;
BarsRequired = 0; // OK to plot on first bar
try
{
Add(Symbol2, BarsPeriod.Id, BarsPeriod.Value);
supportedBarsPeriodType = true;
}
catch(Exception e)
{
Print("Warning : BarsPeriod.Id didn't work");
}
}
/// <summary>
/// Called on each bar update event (incoming tick)
/// </summary>
protected override void OnBarUpdate()
{
if (Displacement + (CalculateOnBarClose ? 1 : 0) > 0 && CurrentBar > 0 && BarColorSeries[1] != Color.Transparent)
InitColorSeries();
if(CurrentBars[0] < 1 || CurrentBars[1] < 1)
return;
//BarColorSeries.Set(Math.Max(0, CurrentBar + Math.Max(0, Displacement) + (CalculateOnBarClose ? 1 : 0)), Color.Transparent);
//CandleOutlineColorSeries.Set(Math.Max(0, CurrentBar + Math.Max(0, Displacement) + (CalculateOnBarClose ? 1 : 0)), Color.Transparent);
SpreadOpen.Set(Qty1*Opens[0][0]+Qty2*Opens[1][0]);
SpreadClose.Set(Qty1*Closes[0][0]+Qty2*Closes[1][0]);
if(Qty1>0)
{
SpreadHigh.Set( Qty1*Highs[0][0] + Math.Max(Qty2*Highs[1][0],Qty2*Lows[1][0]) );
SpreadLow.Set( Qty1*Lows[0][0] + Math.Min(Qty2*Highs[1][0],Qty2*Lows[1][0]) );
}
else
{
SpreadHigh.Set( Qty1*Lows[0][0] + Math.Max(Qty2*Highs[1][0],Qty2*Lows[1][0]) );
SpreadLow.Set( Qty1*Highs[0][0] + Math.Min(Qty2*Highs[1][0],Qty2*Lows[1][0]) );
}
}
#region Properties
[Description("Quantity 1")]
[GridCategory("Parameters")]
// Force this parameter to be displayed first
[Gui.Design.DisplayName ("\t\t\tQuantity 1")]
public double Qty1
{
get { return qty1; }
set { qty1 = value; }
}
[Description("Symbol 2; i.e. SPY or ES 03-10\nDefault = Secondary chart instrument")]
[GridCategory("Parameters")]
// Force this parameter to be displayed second
[Gui.Design.DisplayName ("\t\tSymbol 2")]
public string Symbol2
{
get
{ // symbol2 defaults to secondary chart data series
if ((symbol2 == "") && (ChartControl != null) && (Instruments != null))
for(int i=0; i<ChartControl.BarsArray.Length; i++)
if (ChartControl.BarsArray[i].Instrument.FullName != Instruments[0].FullName)
{
symbol2 = ChartControl.BarsArray[i].Instrument.FullName;
break;
}
return symbol2;
}
set { symbol2 = value.ToUpper(); }
}
[Description("Quantity 2")]
[GridCategory("Parameters")]
[Gui.Design.DisplayName ("\tQuantity 2")]
public double Qty2
{
get { return qty2; }
set { qty2 = value; }
}
[Browsable(false)]
[XmlIgnore]
public DataSeries SpreadOpen
{
get { return Values[0]; }
}
[Browsable(false)]
[XmlIgnore]
public DataSeries SpreadHigh
{
get { return Values[1]; }
}
[Browsable(false)]
[XmlIgnore]
public DataSeries SpreadLow
{
get { return Values[2]; }
}
[Browsable(false)]
[XmlIgnore]
public DataSeries SpreadClose
{
get { return Values[3]; }
}
[XmlIgnore]
[Description("Color of down bars.")]
[Category("Visual")]
[Gui.Design.DisplayNameAttribute("Down color")]
public Color BarColorDown
{
get { return barColorDown; }
set { barColorDown = value; }
}
/// <summary>
/// </summary>
[Browsable(false)]
public string BarColorDownSerialize
{
get { return Gui.Design.SerializableColor.ToString(barColorDown); }
set { barColorDown = Gui.Design.SerializableColor.FromString(value); }
}
/// <summary>
/// </summary>
[XmlIgnore]
[Description("Color of up bars.")]
[Category("Visual")]
[Gui.Design.DisplayNameAttribute("Up color")]
public Color BarColorUp
{
get { return barColorUp; }
set { barColorUp = value; }
}
/// <summary>
/// </summary>
[Browsable(false)]
public string BarColorUpSerialize
{
get { return Gui.Design.SerializableColor.ToString(barColorUp); }
set { barColorUp = Gui.Design.SerializableColor.FromString(value); }
}
/// <summary>
/// </summary>
[XmlIgnore]
[Description("Color of shadow line.")]
[Category("Visual")]
[Gui.Design.DisplayNameAttribute("Shadow color")]
public Color ShadowColor
{
get { return shadowColor; }
set { shadowColor = value; }
}

Comment