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

Wrong values when using DataSeries.Set(int barsAgo, double value) in Indicator

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

    Wrong values when using DataSeries.Set(int barsAgo, double value) in Indicator

    When using the DataSeries.Set(int barsAgo, double value) function for indicator computations like SMA (see short demo example below) wrong values are computed when I use sampling intervals >0 of the input.

    As you can see from the debug output, the most recent 'period' data points are correct (comparing the 4 period example and the 8 period example) but
    the computed SMA is clearly wrong in the 4 period with interval 1 example

    Please provide a hint how a sampling of the input price series can be implemented in a way that can be used as an input for different indicators.

    Thx in advance,
    cbaer

    Debug output: OK
    --------------- SMA Period 8 , Sample intervall between data points 0 ------
    ES:Minute:60:MASample: Date:5/6, Time:06.05.2009 14:00:00
    ES:MASample: CurrentBar=1547, numberOfBarsNecessary=7
    ES:Minute:60:MASample: Date:5/6, Time:06.05.2009 14:00:00
    ES:MASample: CurrentBar=1547, Values: 912,75; 907,25; 908; 906,25; 910,5; 909,75; 897,75; 898,5;
    ES:Minute:60:MASample: Date:5/6, Time:06.05.2009 14:00:00
    ES:MASample: CurrentBar=1547, mAValue: 906,34375

    ERROR:
    --------------- SMA Period 4 , Sample intervall between data points 1 ------
    ES:Minute:60:MASample: Date:5/6, Time:06.05.2009 14:00:00
    ES:MASample: CurrentBar=1547, numberOfBarsNecessary=6
    ES:Minute:60:MASample: Date:5/6, Time:06.05.2009 14:00:00
    ES:MASample: CurrentBar=1547, Values: 912,75; 908; 910,5; 897,75;
    ES:Minute:60:MASample: Date:5/6, Time:06.05.2009 14:00:00
    ES:MASample: CurrentBar=1547, mAValue: 982


    Code:
    // This namespace holds all indicators and is required. Do not change it.
    namespace NinjaTrader.Indicator
    {
        /// <summary>
        /// General Moving Average Indicator: By selecting a integer type one can switch easily between different MA computation algorithms: 0=TEMA 1=HMA 2=ITMA 3=WMA 4=EMA 5=VWMA 6=SMA 7=TMA 8=I_MIDAS(intraday)
        /// </summary>
        [Description("General Moving Average Indicator: By selecting a integer type one can switch easily between different MA computation algorithms: 0=TEMA 1=HMA 2=ITMA 3=WMA 4=EMA 5=VWMA 6=SMA 7=TMA 8=I_MIDAS(intraday)")]
        public class MASampledExp : Indicator
        {
             #region Variables
            // Wizard generated variables
                private        int      period      = 4; // Default setting for Period
                private        int      interval    = 1; 
                private        double   mAValue     = 0;
                
                private DataSeries SampledPricePoints;
    
                private        int      debug       = 3;
    
            
            // 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.Brown), PlotStyle.Line, "MAPlot"));
                Overlay                = true;
                PriceTypeSupported    = true;
                SampledPricePoints = new DataSeries(this);
            }
    
            /// <summary>
            /// Called on each bar update event (incoming tick)
            /// </summary>
            protected override void OnBarUpdate()
            {
                mAValue             = 0;
                double volPriceSum  = 0;
                double volSum        = 0;
                int    count        = 0;
                int    index        = 0;
                
    
                int numberOfBarsNecessary = ((period-1) * (interval+1));
                if (debug > 0)
                {        
                Print(Instrument.MasterInstrument.Name+":"+Bars.Period.Id.ToString() +":"+ 
                                Bars.Period.Value+":"+
                            "MASample: Date:"+Time[0].Month + "/"+ 
                                Time[0].Day+", Time:" + Time[0]);
                Print(Instrument.MasterInstrument.Name+ ":"+
                            "MASample: CurrentBar=" + CurrentBar +
                            ", numberOfBarsNecessary=" + numberOfBarsNecessary);                    
                }
                
                if (CurrentBar <  Math.Max(numberOfBarsNecessary*2,(period*2*(interval+1))+1) )
                {
                    SampledPricePoints.Set(Input[0]);
                    return;
                }
                else
                {
                    // Period times two to make sure enough values are supplied 
                    // to build the indicator
                    for (count = 0; count < period*2 ; count++ )
                    {
                        // According to docu this sets the value 'count' bars ago
                        SampledPricePoints.Set(count,Input[index]);
                        index += (interval+1);
                    }
                }
                
                if (debug > 1)
                {        
                Print(Instrument.MasterInstrument.Name+":"+Bars.Period.Id.ToString() +":"+ 
                                Bars.Period.Value+":"+
                            "MASample: Date:"+Time[0].Month + "/"+ 
                                Time[0].Day+", Time:" + Time[0]);
                    string values = "";
                    for (count = 0; count < period; count += 1)
                    {
                            values += SampledPricePoints[count].ToString() + ";  ";
                    }
    
                Print(Instrument.MasterInstrument.Name+ ":"+
                            "MASample: CurrentBar="+ CurrentBar + 
                                ", Values: " + values );                    
                }
                 
                // This should compute the SMA of the last 'period' values of
                // the SampledPricePoints dataseries but it does not. 
                mAValue = SMA(SampledPricePoints,period)[0];
                
    
                MAPlot.Set(mAValue);
                
                if (debug > 0)
                {        
                Print(Instrument.MasterInstrument.Name+":"+
                            Bars.Period.Id.ToString() +":"+ Bars.Period.Value+":"+
                                "MASample: Date:"+Time[0].Month + "/"+ 
                                    Time[0].Day+", Time:" + Time[0]);
                Print(Instrument.MasterInstrument.Name+ ":"+
                            "MASample: CurrentBar="+ CurrentBar + 
                                ", mAValue: " + mAValue );            
                Print("");
                }
            }
    
            #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 MAPlot
            {
                get { return Values[0]; }
            }
    
            
            [Description("Period for MA computation")]
            [Category("Parameters")]
            public int Period
            {
                get { return period; }
                set { period = Math.Max(1, value); }
            }
            
           [Description("Sample Interval between the Data Points for the MA computation")]
            [Category("Parameters")]
            public int Interval
            {
                get { return interval; }
                set { interval = Math.Max(0, value); }
            }
    
     
            #endregion
        }
    }

    #2
    cbaer,

    Sorry, not following you. What exactly is the issue? You have a lot of extraneous code that we unfortunately do not have the bandwidth to step through. Please just isolate out the core concept of what you are trying to do. Thank you.
    Josh P.NinjaTrader Customer Service

    Comment


      #3
      Originally posted by NinjaTrader_Josh View Post
      cbaer,

      Sorry, not following you. What exactly is the issue? You have a lot of extraneous code that we unfortunately do not have the bandwidth to step through. Please just isolate out the core concept of what you are trying to do. Thank you.
      Ok I strip down the code:

      Code:
          
                  private        int      period      = 4; 
                  private        int     [I] interval    = 1; [/I]
                  
                  private DataSeries SampledPricePoints;
      
        
                  for (count = 0; count < period*2 ; count++ )
                      {
                          // According to docu this sets the value 'count' bars ago
      
                          SampledPricePoints.Set([I][U]count[/U][/I],Input[[U]index[/U]]);
      
                          [U]index [/U]+= ([U]interval[/U]+1);
                      }
                 
                  // This should compute the SMA of the last 'period' values of
                  // the SampledPricePoints dataseries but it does not if 
                  // [U]index[/U] was  > 0
      
                  mAValue = SMA(SampledPricePoints,period)[0];
      ----------- SMA Period 4 , Sample intervall between data points 1 ------

      ES:MASample: CurrentBar=1547, Values: 912,75; 908; 910,5; 897,75;
      ES:MASample: CurrentBar=1547, mAValue: 982 but should be 907,25

      The full code segment you can simply copy and let it run, which should be
      much simpler for you to find the error.

      The DataSeries computation works for intervals of 0 (traditional computation) but if I put in say the latest, 3rd, 5th and 7th data value in the DataSeries SamplePricePoints im Position 0,1,2,3 I get a wrong computation as shown in the debug output above.

      Hope that makes the problem clearer.

      Thx a lot

      cbaer

      Comment


        #4
        cbaer,

        What is your intent in using this the barsAgo parameter for .Set()? What that does is goes back to the previous index values and changes whatever was stored there.
        Josh P.NinjaTrader Customer Service

        Comment


          #5
          Originally posted by NinjaTrader_Josh View Post
          cbaer,

          What is your intent in using this the barsAgo parameter for .Set()? What that does is goes back to the previous index values and changes whatever was stored there.
          That is what it should do. That is what I intended and that is what it does.
          The problem is when you are calling an indicator with this
          created DataSeries. If the values you set in the DataSeries came from bars that were not adjacent the indicator call will not produce the right result.

          Just run the full code with period = 8 and intervall = 0
          which works fine and with period = 4 and intervall > 0
          you will see the error immediatly.

          What is the motivation?
          I need to caclulate indicators not on the last n price points but on n price points that occured at certain intervalls.

          I thought Oh easy just put the values of interest in a DataSeries and call the indicator functions, but as my full
          example shows that does not work when the original values where not taken from successive bars.

          Ciao cbaer

          Comment


            #6
            Not following what you mean by "adjacent" or "interval". You need to ensure you have enough valid data points when set.

            See attached reference. Everything works as expected.

            Sets DataSeries as 1,2,3,4,1,2,3,4 etc.

            SMA period of 5 means (1+2+3+4+1) / 5 = 2.2. That is the output you get when you have enough bars loaded and enough valid points.
            Attached Files
            Josh P.NinjaTrader Customer Service

            Comment


              #7
              Originally posted by NinjaTrader_Josh View Post
              Not following what you mean by "adjacent" or "interval". You need to ensure you have enough valid data points when set.

              See attached reference. Everything works as expected.

              Sets DataSeries as 1,2,3,4,1,2,3,4 etc.

              SMA period of 5 means (1+2+3+4+1) / 5 = 2.2. That is the output you get when you have enough bars loaded and enough valid points.
              If you change datseries value some bar ago and recalculate SMA,
              SMA gives wrong result. See my striped down code here (just from two values)


              I have figured out why, but it is quite misleading...

              Comment


                #8
                Please see the post in your thread.
                Josh P.NinjaTrader Customer Service

                Comment


                  #9
                  Originally posted by NinjaTrader_Josh View Post
                  Not following what you mean by "adjacent" or "interval". You need to ensure you have enough valid data points when set.

                  See attached reference. Everything works as expected.

                  Sets DataSeries as 1,2,3,4,1,2,3,4 etc.

                  SMA period of 5 means (1+2+3+4+1) / 5 = 2.2. That is the output you get when you have enough bars loaded and enough valid points.
                  Hello Josh, hello roonius,

                  thanks so much for your efforts guys, I think we are getting to the point now. Josh if you recalculate every 4 bar like you did in your example everything works fine.

                  But if you would do the calculations everybar you will see that the SMA calculations get completly messed up, like roonius pointed it out in his tread:
                  HTML Code:
                  http://www.ninjatrader-support2.com/vb/showthread.php?t=16824
                  I modified your code for an illustration of the problem. I just removed the modulo line. If you let this code run for example on an ES 1hour chart the SMA will output crazy values.

                  If anybody has an idea how to avoid this problem that would be very nice.

                  Thx cbaer


                  Code:
                  // 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 DSTest : Indicator
                      {
                          #region Variables
                          private DataSeries myDataSeries;
                         #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()
                          {
                              CalculateOnBarClose    = true;
                              Overlay                = false;
                              PriceTypeSupported    = false;
                              
                              myDataSeries        = new DataSeries(this);
                         }
                  
                          /// <summary>
                          /// Called on each bar update event (incoming tick)
                          /// </summary>
                          protected override void OnBarUpdate()
                          {
                              if (CurrentBar < 4)
                                  return;
                              
                                  myDataSeries.Set(0, 1);
                                  myDataSeries.Set(1, 2);
                                  myDataSeries.Set(2, 3);
                                  myDataSeries.Set(3, 4);
                                  Print(Time[0] + " " + SMA(myDataSeries, 5)[0].ToString());
                                  
                              
                          }
                  
                          #region Properties
                  
                          #endregion
                      }
                  }

                  Comment


                    #10
                    cbaer,

                    We are in the process of reviewing the SMA right now. It does not seem to be an issue with DataSeries.Set()ing.
                    Josh P.NinjaTrader Customer Service

                    Comment


                      #11
                      The SMA indicator will not take into account changes in a custom DataSeries. If you wish for this type of behavior you will need to create a variant of the SMA that is calculated off of a loop instead of a stored state.
                      Josh P.NinjaTrader Customer Service

                      Comment

                      Latest Posts

                      Collapse

                      Topics Statistics Last Post
                      Started by benmarkal, Yesterday, 12:52 PM
                      3 responses
                      23 views
                      0 likes
                      Last Post NinjaTrader_Gaby  
                      Started by helpwanted, Today, 03:06 AM
                      1 response
                      19 views
                      0 likes
                      Last Post sarafuenonly123  
                      Started by Brevo, Today, 01:45 AM
                      0 responses
                      11 views
                      0 likes
                      Last Post Brevo
                      by Brevo
                       
                      Started by pvincent, 06-23-2022, 12:53 PM
                      14 responses
                      244 views
                      0 likes
                      Last Post Nyman
                      by Nyman
                       
                      Started by TraderG23, 12-08-2023, 07:56 AM
                      9 responses
                      388 views
                      1 like
                      Last Post Gavini
                      by Gavini
                       
                      Working...
                      X