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

Same values from different time frames on EMA

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

    Same values from different time frames on EMA

    I'm comparing EMA's from different time frames but, debugging reveals the indicator variables have the same value. I must be doing something wrong. Can you point me in the right direction?

    Code:
    else if (State == State.Configure)
    {
    
    // Add the different data series.
    AddDataSeries(Data.BarsPeriodType.Minute, 60);
    AddDataSeries(Data.BarsPeriodType.Minute, 240);
    AddDataSeries(Data.BarsPeriodType.Day, 1);
    
    // Initialize the indicators.
    _60MinuteHighEMA = EMA(Highs[1], 300);
    _60MinuteLowEMA = EMA(Lows[1], 300);
    _1DayHighEMA = EMA(Highs[3], 300);
    _1DayLowEMA = EMA(Lows[3], 300);[ATTACH=JSON]{"data-align":"none","data-size":"full","title":"EMA Similar Values.PNG","data-attachmentid":1114609}[/ATTACH]
    }
    Attached Files

    #2
    Hello Herrwolf1,

    Its difficult to say from the given details, you may want to try and call the indicator prior to the print by copying the code from OnStateChange to OnBarUpdate:

    Code:
    _60MinuteHighEMA = EMA(Highs[1], 300);
    
    Print(....);
    Does that allow for the correct value to be seen?

    If not I would suggest making a new empty indicator and add 1 extra data series/prints as you have in your current script and then attach that sample. We can go over that excluding the other items you had in the script previously.


    I look forward to being of further assistance.
    JesseNinjaTrader Customer Service

    Comment


      #3
      That appears to work. Thank you sir.

      Comment


        #4
        Pursuant to this issue, I'm having a difficult time obtaining a repeating outcome. If I add the following indicator to a 60 minute chart, and set the "Bars Period Type" to "Minute" and the period property to 240, I get the proper outcome. To that end, it always works when initially adding the indicator to a chart. If I change either of those properties, the plotted line matches the 60 minute EMA indicators. This leads me to believe the indicator values are incorrect. You can see this from the attached pictures. What should I be doing differently? I've copied the entire indicator text for your review.

        Thanks,

        Code:
        #region Using declarations
        using System;
        using System.Collections.Generic;
        using System.ComponentModel;
        using System.ComponentModel.DataAnnotations;
        using System.Linq;
        using System.Text;
        using System.Threading.Tasks;
        using System.Windows;
        using System.Windows.Input;
        using System.Windows.Media;
        using System.Xml.Serialization;
        using NinjaTrader.Cbi;
        using NinjaTrader.Gui;
        using NinjaTrader.Gui.Chart;
        using NinjaTrader.Gui.SuperDom;
        using NinjaTrader.Gui.Tools;
        using NinjaTrader.Data;
        using NinjaTrader.NinjaScript;
        using NinjaTrader.Core.FloatingPoint;
        using NinjaTrader.NinjaScript.DrawingTools;
        #endregion
        
        //This namespace holds Indicators in this folder and is required. Do not change it.
        namespace NinjaTrader.NinjaScript.Indicators
        {
        public class Filter : Indicator
        {
        private EMA _300HighEma = null;
        private EMA _300LowEma = null;
        protected override void OnStateChange()
        {
        if (State == State.SetDefaults)
        {
        Description = @"This indicator serves as a trade filter.";
        Name = "Filter";
        Calculate = Calculate.OnBarClose;
        IsOverlay = true;
        DisplayInDataBox = true;
        DrawOnPricePanel = true;
        DrawHorizontalGridLines = true;
        DrawVerticalGridLines = true;
        PaintPriceMarkers = true;
        ScaleJustification = NinjaTrader.Gui.Chart.ScaleJustification.Right;
        //Disable this property if your indicator requires custom values that cumulate with each new market data event.
        //See Help Guide for additional information.
        IsSuspendedWhileInactive = true;
        
        AddPlot(new Stroke(Brushes.Blue, 1), PlotStyle.Line, "Line1");
        AddPlot(new Stroke(Brushes.Khaki, 1), PlotStyle.Line, "Line2");
        }
        else if (State == State.Configure)
        {
        AddDataSeries(PeriodType, Period);
        
        _300HighEma = EMA(Highs[1], 300);
        _300LowEma = EMA(Lows[1], 300);
        }
        else if (State == State.DataLoaded)
        {
        
        }
        }
        
        protected override void OnBarUpdate()
        {
        FilterMarketPosition = MarketPosition.Flat;
        
        //Add your custom indicator logic here.
        if (CurrentBars[1] < 301) return;
        if (BarsInProgress != 0) return;
        
        // Reset the parameters.
        _300HighEma = EMA(Highs[1], 300);
        _300LowEma = EMA(Lows[1], 300);
        
        Line1[0] = _300HighEma[0];
        Line2[0] = _300LowEma[0];
        }
        
        #region <==========Properties==========>
        [NinjaScriptProperty]
        [Display(ResourceType = typeof(Custom.Resource), Name = "BarsPeriodType", Order = 0)]
        public BarsPeriodType PeriodType { get; set; }
        
        [NinjaScriptProperty]
        [Range(1, int.MaxValue)]
        [Display(Description = "Quantity of period type.", Order = 0)]
        public int Period { get; set; }
        
        [Browsable(false)]
        [XmlIgnore]
        public Series<double> Line1
        {
        get { return Values[0]; }
        }
        
        [Browsable(false)]
        [XmlIgnore]
        public Series<double> Line2
        {
        get { return Values[1]; }
        }
        
        [Browsable(false)]
        [XmlIgnore]
        public MarketPosition FilterMarketPosition { get; set; }
        #endregion
        }
        }
        
        #region NinjaScript generated code. Neither change nor remove.
        
        namespace NinjaTrader.NinjaScript.Indicators
        {
        public partial class Indicator : NinjaTrader.Gui.NinjaScript.IndicatorRenderBase
        {
        private Filter[] cacheFilter;
        public Filter Filter(BarsPeriodType periodType, int period)
        {
        return Filter(Input, periodType, period);
        }
        
        public Filter Filter(ISeries<double> input, BarsPeriodType periodType, int period)
        {
        if (cacheFilter != null)
        for (int idx = 0; idx < cacheFilter.Length; idx++)
        if (cacheFilter[idx] != null && cacheFilter[idx].PeriodType == periodType && cacheFilter[idx].Period == period && cacheFilter[idx].EqualsInput(input))
        return cacheFilter[idx];
        return CacheIndicator<Filter>(new Filter(){ PeriodType = periodType, Period = period }, input, ref cacheFilter);
        }
        }
        }
        
        namespace NinjaTrader.NinjaScript.MarketAnalyzerColumns
        {
        public partial class MarketAnalyzerColumn : MarketAnalyzerColumnBase
        {
        public Indicators.Filter Filter(BarsPeriodType periodType, int period)
        {
        return indicator.Filter(Input, periodType, period);
        }
        
        public Indicators.Filter Filter(ISeries<double> input , BarsPeriodType periodType, int period)
        {
        return indicator.Filter(input, periodType, period);
        }
        }
        }
        
        namespace NinjaTrader.NinjaScript.Strategies
        {
        public partial class Strategy : NinjaTrader.Gui.NinjaScript.StrategyRenderBase
        {
        public Indicators.Filter Filter(BarsPeriodType periodType, int period)
        {
        return indicator.Filter(Input, periodType, period);
        }
        
        public Indicators.Filter Filter(ISeries<double> input , BarsPeriodType periodType, int period)
        {
        return indicator.Filter(input, periodType, period);
        }
        }
        }
        
        #endregion
        Attached Files

        Comment


          #5
          Hello Herrwolf1,

          Thank you for the post.

          Its possible that you are running into the warning listed on the AddDataSeries page:
          •Arguments supplied to AddDataSeries() should be hardcoded and NOT dependent on run-time variables which cannot be reliably obtained during State.Configure (e.g., Instrument, Bars, or user input). Attempting to add a data series dynamically is NOT guaranteed and therefore should be avoided. Trying to load bars dynamically may result in an error similar to: Unable to load bars series. Your NinjaScript may be trying to use an additional data series dynamically in an unsupported manner.
          Its possible that you are not seeing the error at all but still seeing an effect related to this. The AddDataSeries is not intended to be variable and there is not a specific list of where that is effected as it is not completely know.

          For this issue I would suggest to run the following steps and see if that makes a difference:

          Hard code the first test period in the indicator: 240 minute
          Compile
          Remove the indicator from where it was applied
          Re apply the indicator
          Hard code the different period: 300 minute
          Compile
          Remove the indicator from where it was applied
          Re apply the indicator

          If you see that is working by following that process we can confirm that is related to the variables. You have the options to hard code the secondary series or know this situation is affected and always remove and add the indicator instead of making changes and relying on it to reload.




          JesseNinjaTrader Customer Service

          Comment


            #6
            Jesse,

            Thanks for the response.

            I've done as you asked. It still works as expected every time the indicator is removed and re-applied. This time I applied the indicator and then hit the F5 key and that resulted in the same issue.

            P.S.: I applied the indicator while using the "Data Box" and took a picture of the data box w/ my phone. After I hit F5, indeed the values do change.

            P.P.S.: I added the PSAR to my indicator as such " _psar = ParabolicSAR(BarsArray[1], 0.02, 0.2, 0.02);" and when I refresh via the F5 key it stays the same. I'm thinking the issue is w/ using the "Highs" or "Lows" etc...
            Last edited by Herrwolf1; 10-16-2020, 03:50 PM.

            Comment


              #7
              Hello Herrwolf1,

              Thank you for the reply.

              Can you attach what you had tested this far so I can test the steps you listed on my end?

              And to clarify, the data box value is changing but the chart is not, is that correct?

              I look forward to being of further assistance.
              JesseNinjaTrader Customer Service

              Comment


                #8
                It's basically the same indicator as before.
                1. Create a 60 minute chart.
                2. Add two 300 EMA indicators. One references the highs and the other references the lows.
                3. Add this "Filter" indicator to the chart.
                4. Set the "Bars Period Type" to minute.
                5. Set the "Period" to 240.
                The initial load displays correctly. Hit F5 and watch the change. There are three moving averages and one PSAR that uses "BarsArray[1]" as the argument and they work as expected (they won't change after the F5 key is hit). It's only the two EMA's that reference the Highs/Lows respectively and they are the issue.

                You should see results similar to the attached pictures.

                Code:
                #region Using declarations
                using System;
                using System.Collections.Generic;
                using System.ComponentModel;
                using System.ComponentModel.DataAnnotations;
                using System.Linq;
                using System.Text;
                using System.Threading.Tasks;
                using System.Windows;
                using System.Windows.Input;
                using System.Windows.Media;
                using System.Xml.Serialization;
                using NinjaTrader.Cbi;
                using NinjaTrader.Gui;
                using NinjaTrader.Gui.Chart;
                using NinjaTrader.Gui.SuperDom;
                using NinjaTrader.Gui.Tools;
                using NinjaTrader.Data;
                using NinjaTrader.NinjaScript;
                using NinjaTrader.Core.FloatingPoint;
                using NinjaTrader.NinjaScript.DrawingTools;
                #endregion
                
                //This namespace holds Indicators in this folder and is required. Do not change it.
                namespace NinjaTrader.NinjaScript.Indicators
                {
                public class Filter : Indicator
                {
                private EMA _ema300 = null;
                private EMA _ema300High = null;
                private EMA _ema300Low = null;
                private ParabolicSAR _psar = null;
                private SMA _sma20 = null;
                private VWMA _vwma20 = null;
                
                protected override void OnStateChange()
                {
                if (State == State.SetDefaults)
                {
                Description = @"This indicator serves as a trade filter.";
                Name = "Filter";
                Calculate = Calculate.OnBarClose;
                IsOverlay = true;
                DisplayInDataBox = true;
                DrawOnPricePanel = true;
                DrawHorizontalGridLines = true;
                DrawVerticalGridLines = true;
                PaintPriceMarkers = true;
                ScaleJustification = NinjaTrader.Gui.Chart.ScaleJustification.Right;
                //Disable this property if your indicator requires custom values that cumulate with each new market data event.
                //See Help Guide for additional information.
                IsSuspendedWhileInactive = true;
                
                AddPlot(new Stroke(Brushes.AliceBlue, 5), PlotStyle.Dot, "PSAR");
                AddPlot(new Stroke(Brushes.GreenYellow, DashStyleHelper.Dot, 4), PlotStyle.Line, "Line20VWMA");
                AddPlot(new Stroke(Brushes.IndianRed, DashStyleHelper.Dash, 4), PlotStyle.Line, "Line20SMA");
                AddPlot(new Stroke(Brushes.Orange, 1), PlotStyle.Line, "Line300");
                AddPlot(new Stroke(Brushes.DarkOrange, 1), PlotStyle.Line, "Line300High");
                AddPlot(new Stroke(Brushes.DarkOrange, 1), PlotStyle.Line, "Line300Low");
                
                }
                else if (State == State.Configure)
                {
                AddDataSeries(PeriodType, Period);
                //AddDataSeries(BarsPeriodType.Minute, 480);
                
                _ema300 = EMA(BarsArray[1], 300);
                _ema300High = EMA(Highs[1], 300); // This is the problem
                _ema300Low = EMA(Lows[1], 300); // This is the problem.
                _psar = ParabolicSAR(BarsArray[1], 0.02, 0.2, 0.02);
                _sma20 = SMA(BarsArray[1], 20);
                _vwma20 = VWMA(BarsArray[1], 20);
                }
                else if (State == State.DataLoaded)
                {
                
                }
                }
                
                protected override void OnBarUpdate()
                {
                FilterMarketPosition = MarketPosition.Flat;
                
                //Add your custom indicator logic here.
                if (CurrentBars[1] &lt; 21) return;
                if (BarsInProgress != 0) return;
                
                // Reset the parameters.
                _ema300 = EMA(BarsArray[1], 300);
                _psar = ParabolicSAR(BarsArray[1], 0.02, 0.2, 0.02);
                _sma20 = SMA(BarsArray[1], 20);
                _vwma20 = VWMA(BarsArray[1], 20);
                _ema300High = EMA(Highs[1], 300);
                _ema300Low = EMA(Lows[1], 300);
                
                if (CurrentBars[1] &gt; 300)
                {
                Line300[0] = _ema300.Value[0];
                Line300High[0] = _ema300High.Value[0];
                Line300Low[0] = _ema300Low.Value[0];
                }
                
                PSAR[0] = _psar.Value[0];
                Line20SMA[0] = _sma20.Value[0];
                Line20VWMA[0] = _vwma20.Value[0];
                
                FilterMarketPosition = _vwma20[0] &gt; _sma20[0] ? MarketPosition.Long : MarketPosition.Short;
                }
                
                #region &lt;==========Properties==========&gt;
                [NinjaScriptProperty]
                [Display(ResourceType = typeof(Custom.Resource), Name = "BarsPeriodType", Order = 0)]
                public BarsPeriodType PeriodType { get; set; }
                
                [NinjaScriptProperty]
                [Range(1, int.MaxValue)]
                [Display(Description = "Quantity of period type.", Order = 0)]
                public int Period { get; set; }
                
                [Browsable(false)]
                [XmlIgnore]
                public Series&lt;double&gt; PSAR
                {
                get { return Values[0]; }
                }
                
                [Browsable(false)]
                [XmlIgnore]
                public Series&lt;double&gt; Line20VWMA
                {
                get { return Values[1]; }
                }
                
                [Browsable(false)]
                [XmlIgnore]
                public Series&lt;double&gt; Line20SMA
                {
                get { return Values[2]; }
                }
                
                
                [Browsable(false)]
                [XmlIgnore]
                public Series&lt;double&gt; Line300
                {
                get { return Values[3]; }
                }
                
                [Browsable(false)]
                [XmlIgnore]
                public Series&lt;double&gt; Line300High
                {
                get { return Values[4]; }
                }
                
                [Browsable(false)]
                [XmlIgnore]
                public Series&lt;double&gt; Line300Low
                {
                get { return Values[5]; }
                }
                
                
                [Browsable(false)]
                [XmlIgnore]
                public MarketPosition FilterMarketPosition { get; set; }
                #endregion
                }
                }
                
                #region NinjaScript generated code. Neither change nor remove.
                
                namespace NinjaTrader.NinjaScript.Indicators
                {
                public partial class Indicator : NinjaTrader.Gui.NinjaScript.IndicatorRenderBase
                {
                private Filter[] cacheFilter;
                public Filter Filter(BarsPeriodType periodType, int period)
                {
                return Filter(Input, periodType, period);
                }
                
                public Filter Filter(ISeries&lt;double&gt; input, BarsPeriodType periodType, int period)
                {
                if (cacheFilter != null)
                for (int idx = 0; idx &lt; cacheFilter.Length; idx++)
                if (cacheFilter[idx] != null &amp;&amp; cacheFilter[idx].PeriodType == periodType &amp;&amp; cacheFilter[idx].Period == period &amp;&amp; cacheFilter[idx].EqualsInput(input))
                return cacheFilter[idx];
                return CacheIndicator&lt;Filter&gt;(new Filter(){ PeriodType = periodType, Period = period }, input, ref cacheFilter);
                }
                }
                }
                
                namespace NinjaTrader.NinjaScript.MarketAnalyzerColumns
                {
                public partial class MarketAnalyzerColumn : MarketAnalyzerColumnBase
                {
                public Indicators.Filter Filter(BarsPeriodType periodType, int period)
                {
                return indicator.Filter(Input, periodType, period);
                }
                
                public Indicators.Filter Filter(ISeries&lt;double&gt; input , BarsPeriodType periodType, int period)
                {
                return indicator.Filter(input, periodType, period);
                }
                }
                }
                
                namespace NinjaTrader.NinjaScript.Strategies
                {
                public partial class Strategy : NinjaTrader.Gui.NinjaScript.StrategyRenderBase
                {
                public Indicators.Filter Filter(BarsPeriodType periodType, int period)
                {
                return indicator.Filter(Input, periodType, period);
                }
                
                public Indicators.Filter Filter(ISeries&lt;double&gt; input , BarsPeriodType periodType, int period)
                {
                return indicator.Filter(input, periodType, period);
                }
                }
                }
                
                #endregion
                Attached Files

                Comment


                  #9
                  Hello Herrwolf1,

                  Thanks for the reply.

                  Do you still see this using the AddDataSeries that is non-variable?

                  Using AddDataSeries as you have is documented to have issues, are you still able to see the problem using AddDataSeries(BarsPeriodType.Minute, 240); instead?

                  Its really not expected for public properties to be used with AddDataSeries and have it work successfully, that mainly happens in backtesting tools but can really happen anywhere the script is applied.


                  I look forward to being of further assistance.
                  JesseNinjaTrader Customer Service

                  Comment


                    #10
                    Yes the results are the same. Variables or hard coded, it makes no difference. The issue is with the Highs/Lows, not the bars array.

                    Comment


                      #11
                      Hello Herrwolf1,

                      Thank you for clarifying that. Going forward I would suggest removing any dynamic uses of AddDataSeries for forum samples as we will always ask that you change that before testing, it just speeds up finding the problem.

                      In regard to the ParabolicSAR, passing a series to it would be unexpected because it does not take an input in its code. All indicators have an overload which you can pass an input but not all make use of that. The ParabolicSAR does not use Input in its code and uses specific Price series. To have this indicator calculate for the second series you would have to call it from that BarsInProgress:

                      Code:
                      if(BarsInProgress == 1)
                      {
                          _psar = ParabolicSAR(0.02, 0.2, 0.02);
                      }
                      The VWMA SMA and EMA all use Input in their logic so those could have a secondary series passed to them.

                      For this type of use case I would likely suggest to use the BarsInProgress property for those indicators to call them on each OBU:

                      Code:
                      //if (BarsInProgress != 0) return;
                      
                      if(BarsInProgress == 0)
                      {
                          existing logic
                      }
                      if(BarsInProgress == 1)
                      {
                         // Reset the parameters.
                      _ema300 = EMA(300);
                      _psar = ParabolicSAR(0.02, 0.2, 0.02);
                      _sma20 = SMA(20);
                      _vwma20 = VWMA( 20);
                      _ema300High = EMA(300);
                      _ema300Low = EMA( 300);
                      }
                      This avoids having to deal with input and only configures the indicators when the secondary series is called.

                      I was unable to test the code you provided to see if that changes the result, the code you pasted got formatted and is no longer completely valid. You can instead attach the .cs file directly if another sample is still needed.


                      I look forward to being of further assistance.
                      JesseNinjaTrader Customer Service

                      Comment

                      Latest Posts

                      Collapse

                      Topics Statistics Last Post
                      Started by StrongLikeBull, Yesterday, 04:05 PM
                      1 response
                      12 views
                      0 likes
                      Last Post NinjaTrader_Gaby  
                      Started by Mestor, 03-10-2023, 01:50 AM
                      14 responses
                      375 views
                      0 likes
                      Last Post z.franck  
                      Started by molecool, 10-09-2017, 10:48 AM
                      5 responses
                      1,621 views
                      0 likes
                      Last Post trader-ap  
                      Started by The_Sec, Yesterday, 03:53 PM
                      1 response
                      12 views
                      0 likes
                      Last Post NinjaTrader_Gaby  
                      Started by mmenigma, Yesterday, 03:25 PM
                      1 response
                      11 views
                      0 likes
                      Last Post NinjaTrader_Gaby  
                      Working...
                      X