Announcement

Collapse
No announcement yet.

Partner 728x90

Collapse

Writing a simple indicator

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

    Writing a simple indicator

    I've written a bunch of strategies, but I have yet to write an indicator. So, last night I gave it a try. Starting with the wizard, I tried to do something very simple. But it isn't doing what I want. Can someone straighten me out? This has got to be something very simple for you experienced guys.

    Code:
    #region Using declarations
    using System;
    using System.ComponentModel;
    using System.Diagnostics;
    using System.Drawing;
    using System.Drawing.Drawing2D;
    using System.Xml.Serialization;
    using NinjaTrader.Cbi;
    using NinjaTrader.Data;
    using NinjaTrader.Gui.Chart;
    #endregion
    
    // This namespace holds all indicators and is required. Do not change it.
    namespace NinjaTrader.Indicator
    {
        /// <summary>
        /// Enter the description of your new custom indicator here
        /// </summary>
        [Description("Enter the description of your new custom indicator here")]
        public class EMAWidth2 : Indicator
        {
            #region Variables
            // Wizard generated variables
                private int slowA = 3; // Default setting for SlowA
                private int slowB = 15; // Default setting for SlowB
            // User defined variables (add any user defined variables below)
            #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.FromKnownColor(KnownColor.Red), PlotStyle.Line, "Short16"));
                //Add(new Plot(Color.FromKnownColor(KnownColor.Green), PlotStyle.Line, "Short12"));
                Add(new Line(Color.DarkViolet, 0, "Center"));
                CalculateOnBarClose    = true;
                Overlay                = false;
                PriceTypeSupported    = false;
            }
    
            /// <summary>
            /// Called on each bar update event (incoming tick)
            /// </summary>
            protected override void OnBarUpdate()
            {
                // Use this method for calculating your indicator values. Assign a value to each
                // plot below by replacing 'Close[0]' with your own formula.
    
                
                if (CurrentBar > 20) 
                {
                    
                    Short16.Set(EMA(slowA)[0] - EMA(slowB)[0]);
                    
                }
                
                
            }
    
            #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 Short16
            {
                get { return Values[0]; }
            }
    
    //        [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 Short12
    //        {
    //            get { return Values[1]; }
    //        }
    
            [Description("")]
            [GridCategory("Parameters")]
            public int SlowA
            {
                get { return slowA; }
                set { slowA = Math.Max(50, value); }
            }
    
            [Description("")]
            [GridCategory("Parameters")]
            public int SlowB
            {
                get { return slowB; }
                set { slowB = Math.Max(50, value); }
            }
            #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 EMAWidth2[] cacheEMAWidth2 = null;
    
            private static EMAWidth2 checkEMAWidth2 = new EMAWidth2();
    
            /// <summary>
            /// Enter the description of your new custom indicator here
            /// </summary>
            /// <returns></returns>
            public EMAWidth2 EMAWidth2(int slowA, int slowB)
            {
                return EMAWidth2(Input, slowA, slowB);
            }
    
            /// <summary>
            /// Enter the description of your new custom indicator here
            /// </summary>
            /// <returns></returns>
            public EMAWidth2 EMAWidth2(Data.IDataSeries input, int slowA, int slowB)
            {
                if (cacheEMAWidth2 != null)
                    for (int idx = 0; idx < cacheEMAWidth2.Length; idx++)
                        if (cacheEMAWidth2[idx].SlowA == slowA && cacheEMAWidth2[idx].SlowB == slowB && cacheEMAWidth2[idx].EqualsInput(input))
                            return cacheEMAWidth2[idx];
    
                lock (checkEMAWidth2)
                {
                    checkEMAWidth2.SlowA = slowA;
                    slowA = checkEMAWidth2.SlowA;
                    checkEMAWidth2.SlowB = slowB;
                    slowB = checkEMAWidth2.SlowB;
    
                    if (cacheEMAWidth2 != null)
                        for (int idx = 0; idx < cacheEMAWidth2.Length; idx++)
                            if (cacheEMAWidth2[idx].SlowA == slowA && cacheEMAWidth2[idx].SlowB == slowB && cacheEMAWidth2[idx].EqualsInput(input))
                                return cacheEMAWidth2[idx];
    
                    EMAWidth2 indicator = new EMAWidth2();
                    indicator.BarsRequired = BarsRequired;
                    indicator.CalculateOnBarClose = CalculateOnBarClose;
    #if NT7
                    indicator.ForceMaximumBarsLookBack256 = ForceMaximumBarsLookBack256;
                    indicator.MaximumBarsLookBack = MaximumBarsLookBack;
    #endif
                    indicator.Input = input;
                    indicator.SlowA = slowA;
                    indicator.SlowB = slowB;
                    Indicators.Add(indicator);
                    indicator.SetUp();
    
                    EMAWidth2[] tmp = new EMAWidth2[cacheEMAWidth2 == null ? 1 : cacheEMAWidth2.Length + 1];
                    if (cacheEMAWidth2 != null)
                        cacheEMAWidth2.CopyTo(tmp, 0);
                    tmp[tmp.Length - 1] = indicator;
                    cacheEMAWidth2 = 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>
            /// Enter the description of your new custom indicator here
            /// </summary>
            /// <returns></returns>
            [Gui.Design.WizardCondition("Indicator")]
            public Indicator.EMAWidth2 EMAWidth2(int slowA, int slowB)
            {
                return _indicator.EMAWidth2(Input, slowA, slowB);
            }
    
            /// <summary>
            /// Enter the description of your new custom indicator here
            /// </summary>
            /// <returns></returns>
            public Indicator.EMAWidth2 EMAWidth2(Data.IDataSeries input, int slowA, int slowB)
            {
                return _indicator.EMAWidth2(input, slowA, slowB);
            }
        }
    }
    
    // This namespace holds all strategies and is required. Do not change it.
    namespace NinjaTrader.Strategy
    {
        public partial class Strategy : StrategyBase
        {
            /// <summary>
            /// Enter the description of your new custom indicator here
            /// </summary>
            /// <returns></returns>
            [Gui.Design.WizardCondition("Indicator")]
            public Indicator.EMAWidth2 EMAWidth2(int slowA, int slowB)
            {
                return _indicator.EMAWidth2(Input, slowA, slowB);
            }
    
            /// <summary>
            /// Enter the description of your new custom indicator here
            /// </summary>
            /// <returns></returns>
            public Indicator.EMAWidth2 EMAWidth2(Data.IDataSeries input, int slowA, int slowB)
            {
                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.EMAWidth2(input, slowA, slowB);
            }
        }
    }
    #endregion
    I expected the indicator would draw a simple plot of the EMA. But instead, it remains at zero. If you replace:

    Short16.Set(EMA(slowA)[0] - EMA(slowB)[0]);

    with:

    Short16.Set(EMA(3)[0] - EMA(15)[0]);

    It works fine. But with the slowA and slowB, it doesn't plot as I'd expect. What do I need to insert in there to use the slowA and slowB?

    #2
    Hi LookOutBelow,

    The issue here is with the Min value you specified when setting this up in the wizard. You used a value of 50, so it's using this instead of the input value. You're then taking EMA(50) - EMA(50) = 0. You can resolve in code with the changes indicated below:


    [Description("")]
    [GridCategory("Parameters")]
    public int SlowA
    {
    get { return slowA; }
    set { slowA = Math.Max(1, value); }
    }

    [Description("")]
    [GridCategory("Parameters")]
    public int SlowB
    {
    get { return slowB; }
    set { slowB = Math.Max(1, value); }
    }
    Ryan M.NinjaTrader Customer Service

    Comment


      #3
      Doh! I knew I overlooked something stupid.

      Thanks. I appreciate it.

      Comment

      Latest Posts

      Collapse

      Topics Statistics Last Post
      Started by Geovanny Suaza, 02-11-2026, 06:32 PM
      0 responses
      583 views
      0 likes
      Last Post Geovanny Suaza  
      Started by Geovanny Suaza, 02-11-2026, 05:51 PM
      0 responses
      339 views
      1 like
      Last Post Geovanny Suaza  
      Started by Mindset, 02-09-2026, 11:44 AM
      0 responses
      103 views
      0 likes
      Last Post Mindset
      by Mindset
       
      Started by Geovanny Suaza, 02-02-2026, 12:30 PM
      0 responses
      554 views
      1 like
      Last Post Geovanny Suaza  
      Started by RFrosty, 01-28-2026, 06:49 PM
      0 responses
      552 views
      1 like
      Last Post RFrosty
      by RFrosty
       
      Working...
      X