Announcement

Collapse

Looking for a User App or Add-On built by the NinjaTrader community?

Visit NinjaTrader EcoSystem and our free User App Share!

Have a question for the NinjaScript developer community? Open a new thread in our NinjaScript File Sharing Discussion Forum!
See more
See less

Partner 728x90

Collapse

Indicator for charting futures spreads (butterfly, condor)

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    Indicator for charting futures spreads (butterfly, condor)

    Hello,
    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:

    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; }
            }

    #2
    (continued)

    Code:
            /// <summary>
            /// </summary>
            [Browsable(false)]
            public string ShadowColorSerialize
            {
                get { return Gui.Design.SerializableColor.ToString(shadowColor); }
                set { shadowColor = Gui.Design.SerializableColor.FromString(value); }
            }
    
            /// <summary>
            /// </summary>
            [Description("Width of shadow line.")]
            [Category("Visual")]
            [Gui.Design.DisplayNameAttribute("Shadow width")]
            public int ShadowWidth
            {
                get { return shadowWidth; }
                set { shadowWidth = Math.Max(value, 1); }
            }
    
            #endregion
    
            #region Miscellaneous
    
            private void InitColorSeries()
            {
                for (int i = 0; i <= CurrentBar + Displacement + (CalculateOnBarClose ? 1 : 0); i++)
                {
                    BarColorSeries.Set(i, Color.Transparent);
                    CandleOutlineColorSeries.Set(i, Color.Transparent);
                }
            }
    
            protected override void OnStartUp()
            {
                if (ChartControl == null || Bars == null)
                    return;
    
                if (!supportedBarsPeriodType)
                    throw new ArgumentException("Input series Period must be time-based (Minute,Day,Week,Month,Year,or Second).");
                
                brushUp                             = new SolidBrush(barColorUp);
                brushDown                           = new SolidBrush(barColorDown);
                shadowPen                           = new Pen(shadowColor, shadowWidth);
            }
    
            protected override void OnTermination()
            {
                if (brushUp != null) brushUp.Dispose();
                if (brushDown != null) brushDown.Dispose();
                if (shadowPen != null) shadowPen.Dispose();
            }
    
            public override void GetMinMaxValues(ChartControl chartControl, ref double min, ref double max)
            {
                if (Bars == null || ChartControl == null)
                    return;
    
                for (int idx = FirstBarIndexPainted; idx <= LastBarIndexPainted; idx++)
                {
                    double tmpHigh = SpreadHigh.Get(idx);
                    double tmpLow = SpreadLow.Get(idx);
    
                    if (tmpHigh != 0 && tmpHigh > max)
                        max = tmpHigh;
                    if (tmpLow != 0 && tmpLow < min)
                        min = tmpLow;
                }
            }
    
            public override void Plot(Graphics graphics, Rectangle bounds, double min, double max)
            {
                if (Bars == null || ChartControl == null)
                    return;
    
                int barPaintWidth = Math.Max(3, 1 + 2 * ((int)Bars.BarsData.ChartStyle.BarWidth - 1) + 2 * shadowWidth);
    
                for (int idx = FirstBarIndexPainted; idx <= LastBarIndexPainted; idx++)
                {
                    if (idx - Displacement < 0 || idx - Displacement  >= BarsArray[0].Count || (!ChartControl.ShowBarsRequired &&  idx - Displacement < BarsRequired))
                        continue;
                    double valH = SpreadHigh.Get(idx);
                    double valL = SpreadLow.Get(idx);
                    double valC = SpreadClose.Get(idx);
                    double valO = SpreadOpen.Get(idx);
                    int x = ChartControl.GetXByBarIdx(BarsArray[0], idx);
                    int y1 = ChartControl.GetYByValue(this, valO);
                    int y2 = ChartControl.GetYByValue(this, valH);
                    int y3 = ChartControl.GetYByValue(this, valL);
                    int y4 = ChartControl.GetYByValue(this, valC);
    
                    graphics.DrawLine(shadowPen, x, y2, x, y3);
    
                    if (y4 == y1)
                        graphics.DrawLine(shadowPen, x - barPaintWidth / 2, y1, x + barPaintWidth / 2, y1);
                    else
                    {
                        if (y4 > y1)
                            graphics.FillRectangle(brushDown, x - barPaintWidth / 2, y1, barPaintWidth, y4 - y1);
                        else
                            graphics.FillRectangle(brushUp, x - barPaintWidth / 2, y4, barPaintWidth, y1 - y4);
                        graphics.DrawRectangle(shadowPen, (x - barPaintWidth  / 2) + (shadowPen.Width / 2), Math.Min(y4, y1), barPaintWidth -  shadowPen.Width, Math.Abs(y4 - y1));
                    }
                }
            }
            #endregion
        }
    }
    
    #region NinjaScript generated code. Neither change nor remove.
    // This namespace holds all indicators and is required. Do not change it.
    namespace NinjaTrader.Indicator
    {
        public partial class Indicator : IndicatorBase
        {
            private SpreadCandlesticks[] cacheSpreadCandlesticks = null;
    
            private static SpreadCandlesticks checkSpreadCandlesticks = new SpreadCandlesticks();
    
            /// <summary>
            /// SpreadCandlesticks
            /// </summary>
            /// <returns></returns>
            public SpreadCandlesticks SpreadCandlesticks(double qty1, double qty2, string symbol2)
            {
                return SpreadCandlesticks(Input, qty1, qty2, symbol2);
            }
    
            /// <summary>
            /// SpreadCandlesticks
            /// </summary>
            /// <returns></returns>
            public SpreadCandlesticks SpreadCandlesticks(Data.IDataSeries input, double qty1, double qty2, string symbol2)
            {
                if (cacheSpreadCandlesticks != null)
                    for (int idx = 0; idx < cacheSpreadCandlesticks.Length; idx++)
                        if (Math.Abs(cacheSpreadCandlesticks[idx].Qty1 -  qty1) <= double.Epsilon &&  Math.Abs(cacheSpreadCandlesticks[idx].Qty2 - qty2) <= double.Epsilon  && cacheSpreadCandlesticks[idx].Symbol2 == symbol2 &&  cacheSpreadCandlesticks[idx].EqualsInput(input))
                            return cacheSpreadCandlesticks[idx];
    
                lock (checkSpreadCandlesticks)
                {
                    checkSpreadCandlesticks.Qty1 = qty1;
                    qty1 = checkSpreadCandlesticks.Qty1;
                    checkSpreadCandlesticks.Qty2 = qty2;
                    qty2 = checkSpreadCandlesticks.Qty2;
                    checkSpreadCandlesticks.Symbol2 = symbol2;
                    symbol2 = checkSpreadCandlesticks.Symbol2;
    
                    if (cacheSpreadCandlesticks != null)
                        for (int idx = 0; idx < cacheSpreadCandlesticks.Length; idx++)
                            if (Math.Abs(cacheSpreadCandlesticks[idx].Qty1 -  qty1) <= double.Epsilon &&  Math.Abs(cacheSpreadCandlesticks[idx].Qty2 - qty2) <= double.Epsilon  && cacheSpreadCandlesticks[idx].Symbol2 == symbol2 &&  cacheSpreadCandlesticks[idx].EqualsInput(input))
                                return cacheSpreadCandlesticks[idx];
    
                    SpreadCandlesticks indicator = new SpreadCandlesticks();
                    indicator.BarsRequired = BarsRequired;
                    indicator.CalculateOnBarClose = CalculateOnBarClose;
    #if NT7
                    indicator.ForceMaximumBarsLookBack256 = ForceMaximumBarsLookBack256;
                    indicator.MaximumBarsLookBack = MaximumBarsLookBack;
    #endif
                    indicator.Input = input;
                    indicator.Qty1 = qty1;
                    indicator.Qty2 = qty2;
                    indicator.Symbol2 = symbol2;
                    Indicators.Add(indicator);
                    indicator.SetUp();
    
                    SpreadCandlesticks[] tmp = new  SpreadCandlesticks[cacheSpreadCandlesticks == null ? 1 :  cacheSpreadCandlesticks.Length + 1];
                    if (cacheSpreadCandlesticks != null)
                        cacheSpreadCandlesticks.CopyTo(tmp, 0);
                    tmp[tmp.Length - 1] = indicator;
                    cacheSpreadCandlesticks = tmp;
                    return indicator;
                }
            }
        }
    }
    
    // This namespace holds all market analyzer column definitions and is required. Do not change it.
    namespace NinjaTrader.MarketAnalyzer
    {
        public partial class Column : ColumnBase
        {
            /// <summary>
            /// SpreadCandlesticks
            /// </summary>
            /// <returns></returns>
            [Gui.Design.WizardCondition("Indicator")]
            public Indicator.SpreadCandlesticks SpreadCandlesticks(double qty1, double qty2, string symbol2)
            {
                return _indicator.SpreadCandlesticks(Input, qty1, qty2, symbol2);
            }
    
            /// <summary>
            /// SpreadCandlesticks
            /// </summary>
            /// <returns></returns>
            public Indicator.SpreadCandlesticks SpreadCandlesticks(Data.IDataSeries input, double qty1, double qty2, string symbol2)
            {
                return _indicator.SpreadCandlesticks(input, qty1, qty2, symbol2);
            }
        }
    }
    
    // This namespace holds all strategies and is required. Do not change it.
    namespace NinjaTrader.Strategy
    {
        public partial class Strategy : StrategyBase
        {
            /// <summary>
            /// SpreadCandlesticks
            /// </summary>
            /// <returns></returns>
            [Gui.Design.WizardCondition("Indicator")]
            public Indicator.SpreadCandlesticks SpreadCandlesticks(double qty1, double qty2, string symbol2)
            {
                return _indicator.SpreadCandlesticks(Input, qty1, qty2, symbol2);
            }
    
            /// <summary>
            /// SpreadCandlesticks
            /// </summary>
            /// <returns></returns>
            public Indicator.SpreadCandlesticks SpreadCandlesticks(Data.IDataSeries input, double qty1, double qty2, string symbol2)
            {
                if (InInitialize && input == null)
                    throw new ArgumentException("You only can access an  indicator with the default input/bar series from within the  'Initialize()' method");
    
                return _indicator.SpreadCandlesticks(input, qty1, qty2, symbol2);
            }
        }
    }
    #endregion
    where within the code should 'symbol3' be created, and which lines should be mimicked for its creation?

    Comment


      #3
      Hello CB001,

      You would want to follow how the private variable was created for symbol2 and then the public property for Symbol2

      This will allow you to set up the same user defined property as the Symbol2 is using.

      Let me know if I can be of further assistance.
      Cal H.NinjaTrader Customer Service

      Comment

      Latest Posts

      Collapse

      Topics Statistics Last Post
      Started by FrancisMorro, Today, 03:24 AM
      0 responses
      1 view
      0 likes
      Last Post FrancisMorro  
      Started by Segwin, 05-07-2018, 02:15 PM
      10 responses
      1,769 views
      0 likes
      Last Post Leafcutter  
      Started by Rapine Heihei, 04-23-2024, 07:51 PM
      2 responses
      30 views
      0 likes
      Last Post Max238
      by Max238
       
      Started by Shansen, 08-30-2019, 10:18 PM
      24 responses
      943 views
      0 likes
      Last Post spwizard  
      Started by Max238, Today, 01:28 AM
      0 responses
      10 views
      0 likes
      Last Post Max238
      by Max238
       
      Working...
      X