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

Improved SMA

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

    Improved SMA

    I am writing an improved version of the SMA indicator, due to 3 problems with the existing built-in version:

    Problem 1: For small (<21) Period existing SMA takes too long to display.
    Example: If user has a 60 minute bar chart and SMA(2), they would expect this to start to display after 2 hours, But currently the user has to wait for 21 hours! (assuming a datafeed where you cant fetch historical minute bars).
    This is because the current NT code does not set BarsRequired, so its value seems to default to 20.

    Solution: Set BarsRequired=1


    Problem 2: For large (>21) period existing SMA displays misleading value until Period bars have been received.
    Example: If user requests display of SMA(100) this will actually be displaying SMA(21) at 21st bar, SMA(22) at 22nd bar etc, and is only accurate when reaches 100th bar.

    Solution: Don't start setting value until Period (non null) bars have been received.


    Problem 3: If an Input value has not been Set then NT just includes the Close value for that bar in the SMA.
    This gives inaccurate average in cases where SMA is being used on an "Input Series" which is an indicator where the values are sometimes not set by user (to indicate "unknown" or "not applicable" or "no solution" as per Null in SQL).

    Solution: NT need to expose to user the state of Input[i] (has it been Set or not?).
    The information must already exist inside NT otherwise ContainsValue (on a specific named series) would not work.
    How about exposing the state using something like "InputIsSet[i]" eg
    Code:
    if (InputIsSet[i])
    {//include Input[i] in the average
    }
    or
    Code:
    if (Input.ContainsValue(i))
    or
    Code:
    if (Input[i].IsSet)
    But until NT expose the state of Input[i] using something like this I am unable to solve problem 3.
    Instead I have to use a kludge such as "always set a value in indicator once you start setting values, even if the value is really unknown (so dont want to set)".
    In SQL using AVG on a column with nulls, excludes the nulls from the calculation, Users should be able to implement something similar in NT if they require this.

    #2
    if (Input.ContainsValue(i)) is a boolean value, so it should be usable to determine whether to include a value in a calculation or not.

    You would just have to use a while loop instead of a for loop, and make the exit condition correspond to the number of values you want, and use a continue statement to force a skip when ContainsValue() is false.
    Last edited by koganam; 10-26-2011, 10:45 AM.

    Comment


      #3
      Hello,

      Thanks for your patience. I reviewed your questions.

      1) You can add BarsRequired = 0; in Initialize() to override the default of 20. However if no setting is supplied it will default to 20. This is by design.

      2) This is specific NT design on our system indicators to allow to display the unstable period. You can of course code your own version of the SMA that does not plot until it is stable. Due to many reasons however we allow this in NinjaTraders default indicators and is specifically coded this way. I will make sure the development is aware of your request to not plot until fully Initialized.

      3) .ContainsValue exists for this purpose. There is specific programming reasons why we use the close price if a value is not set. If you have a scenario when this could happen in your indicator it is important that you check .ContainsValue as shown in this sample and also Koganam shows.



      Let me know if I can be of further assistance.

      Comment


        #4
        Originally posted by koganam View Post
        if (Input.ContainsValue(i)) is a boolean value, so it should be usable to determine whether to include a value in a calculation or not.
        .
        This sounds great in theory. Only problem is that NT have not implemented this.

        If you actually try to put this code in an indicator (as of NT 7.0.1000.7) eg
        Code:
        if (Input.ContainsValue(0))
        		{
                    	 Value.Set(1);
        		}
        		else
        		{
        		 Value.Set(0);
        		}
        ... you will get this error:

        NinjaTrader.Data.IDataSeries' does not contain a definition for 'ContainsValue' and no extension method 'ContainsValue' accepting a first argument of type 'NinjaTrader.Data.IDataSeries' could be found

        Comment


          #5
          I will check into this with development to see if there is a way to check this on Input.

          Comment


            #6
            Hello,


            Thanks again for patience. Since this is an IDataSeries which is not the same thing as DataSeries you will instead use .IsValidPlot(0). As shown below and is in the help guide for IDataSeries.


            http://www.ninjatrader.com/support/helpGuides/nt7/idataseries.htm



            Tips
            1. When working with IDataSeries objects in your code you may come across situations where you are not sure if the value being accessed is a valid value or just a "placeholder" value. To check if you are using valid values for your logic calculations that have been explicitly set, please use .IsValidPlot(int barIdx)to check.
            protected override void OnBarUpdate()
            {

            // Only set our plot if the input is a valid value
            if (Input.IsValidPlot(CurrentBar))
            Plot0.Set(Input[0]);
            }

            Comment


              #7
              Hello Brett,

              I'm glad that you mention the documentation about IsValidPlot, I was just going to paste that myself.
              The problem is that IsValidPlot does not yet seem to have been fully implemented.

              For example if I create an indicator TestValidPlot and put this code into OnBarUpdate()

              Code:
              if (Input.IsValidPlot(0))
              {
                    	Value.Set(1);//get this (for ALL bars) if first bar of Input series was Set
              }
              else
              {
              	Value.Set(0);//Get this (for ALL bars) if first bar of Input series was NOT Set
              }
              and put this into Initialize()

              Code:
              BarsRequired=0;
              Then display this on a chart, setting the indicator's "Input Series" to various types of Indicator then I get the results summarized in the comments in the above code.

              So for instance if I set the indicator's "Input Series" to a built-in NT indicator then I struggle to find one that does not Set every bar (regardless of mathematical correctness). So for instance if I set "Input Series" for TestValidPlot to LinReg(50) (which sets every single bar regardless of mathematical sense) then all bars in TestValidPlot are 1.
              But if I set "Input Series" for TestValidPlot to LinReg2(50) (my corrected version which does not set any bars until the 50th bar) then all bars in TestValidPlot are 0.

              Conclusion: It looks as though a programmer has misunderstood the specification for implementing IsValidPlot, because currently it only seems to be looking at the status of the first bar (CurrentBar==0)

              Comment


                #8
                Hello,

                Correct all base indicators in NinjaTrader will h ave "valid plots" from the start of CurrentBar = 1. This is be design even if the indicator value is not yet stable or fully init(). IsValidPlot is only met to check programatically that the iDataSeries has a valid set value.

                If it does not have a valid set value in the code (Meaning a .set command was not used in that OnBarUpdate()) then you should see a negative return on this IsValidPlot() command.

                Let me know if I can be of further assistance.

                Comment


                  #9
                  Hello Brett,

                  I just noticed that the example code in documentation now says
                  Code:
                  if (Input.IsValidPlot(CurrentBar))
                  Whereas I was expecting IsValidPlot would be using an index with zero as current bar and increasing looking backwards (as per general use in NT including ContainsValue);
                  In fact IsValidPlot uses an index with zero as 1st bar and increasing looking forwards (as per CurrentBar property).

                  I see from the release notes that this was something added for 7.0.1000.7.

                  I would like to thank the NT team for adding this facility, and will assume its unusual indexing is just an oddity we will have to live with.

                  Comment

                  Latest Posts

                  Collapse

                  Topics Statistics Last Post
                  Started by Vietanhnguyen2hotmailcom, Yesterday, 10:29 AM
                  4 responses
                  23 views
                  0 likes
                  Last Post Vietanhnguyen2hotmailcom  
                  Started by PhillT, 04-19-2024, 02:16 PM
                  4 responses
                  35 views
                  0 likes
                  Last Post PhillT
                  by PhillT
                   
                  Started by ageeholdings, 05-01-2024, 05:22 AM
                  5 responses
                  37 views
                  0 likes
                  Last Post ageeholdings  
                  Started by reynoldsn, Today, 02:34 PM
                  0 responses
                  13 views
                  0 likes
                  Last Post reynoldsn  
                  Started by nightstalker, Today, 02:05 PM
                  0 responses
                  23 views
                  0 likes
                  Last Post nightstalker  
                  Working...
                  X