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

Calling SMA on Custom Indicator

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

    Calling SMA on Custom Indicator

    I've created a sample Indicator to demonstrate a problem I am having. My sample Adds a Data series and sums the volume of that data series on each tick using OnMarketData. This is the code:

    Code:
        public class MicrosoftBuySell : Indicator
        {
            private double    volume;
            private int activeBar = 0;
    
            protected override void OnStateChange()
            {
                if (State == State.SetDefaults)
                {
                    Description                = NinjaTrader.Custom.Resource.NinjaScriptIndicatorDescriptionBuySellVolume;
                    Name                    = "MicrosoftBuySell";
                    Calculate                = Calculate.OnEachTick;
                    DrawOnPricePanel        = false;
                    IsOverlay                = false;
                    DisplayInDataBox        = true;
                    AddPlot(new Stroke(Brushes.DarkCyan,    2), PlotStyle.Bar,"MyVolume");
                }
                else if (State == State.Configure){
                    AddDataSeries("MSFT");
                }
            }
    
            protected override void OnMarketData(MarketDataEventArgs e)
            {
                if(BarsInProgress == 0) return;
                if(e.MarketDataType == MarketDataType.Last)
                {
                    volume+=e.Volume;
                }
            }
    
            protected override void OnBarUpdate()
            {
                if (CurrentBar < activeBar || CurrentBar <= BarsRequiredToPlot)
                    return;
    
                // New Bar has been formed
                // - Assign last volume counted to the prior bar
                // - Reset volume count for new bar
                if (CurrentBar != activeBar)
                {
                    MyVolume[1] = volume;
                    volume = 0;
                    activeBar = CurrentBar;
                }
    
                MyVolume[0] = volume;
            }
    
            #region Properties
            [Browsable(false)]
            [XmlIgnore]
            public Series<double> MyVolume
            {
                get { return Values[0]; }
            }
            #endregion
    
        }
    The Indicator plots fine but when I try to add a built in SMA and point to my Indicator as the data series, the MA plots values that are way off and just don't make sense.

    #2
    Hello swcooke,

    I took a look at the script and as far as I can tell this is caused by how you are setting the indicators plot.
    The line:
    Code:
    MyVolume[0] = volume;
    is what is causing the problem when I run it, this is not providing a value for the current bar which creates the error. When I run this while another indicator calls the script volume is equal to 0 when setting the plot.


    If you remove this line
    MyVolume[0] = volume;

    and instead set the current bars value from the condition you have I see it working:
    Code:
     
      MyVolume[1] = volume;
    to
    Code:
      
      MyVolume[0] = volume;
    I look forward to being of further assistance.


    JesseNinjaTrader Customer Service

    Comment


      #3
      Jesse,

      I got this design pattern from the built in BuySellVolume Indicator in NT since I need to update on each tick. Please look at the OnBarUpdate method in that indicator and you can see that mine is identical. Any guidance would be appreciated. The value of the SMA is all over the place and does not look like it should. But if I add the SMA using BuySellVolume, it looks fine.
      Last edited by swcooke; 02-12-2020, 03:44 PM.

      Comment


        #4
        Hello swcooke,

        Right however that indicator only uses one series and was not designed with this scenario in mind. The BuySellVolume is intended to be used only in realtime with a single series per what is documented for the samples. That also assumes it will use its plot to store values as it calculates in realtime, that is what the reset is for in that script. At the start of the next bar it resets the plot to 0 and then sets the previous plots value to the actual accumulation. This type of logic will not work for an input with another script because it does not set a current value and the other script is checking the current values.

        The following prints can help to see this in more detail:


        Code:
            Print("Begin OBU: CurrentBar: " +  CurrentBar + " activeBar: " + activeBar + " volume: " + volume);
                    if (CurrentBar != activeBar)
                    {
                        MyVolume[1] = volume;
                        volume = 0;
                        activeBar = CurrentBar;
                    }
        
                    MyVolume[0] = volume;
                        Print("End OBU: CurrentBar: " +  CurrentBar + " activeBar: " + activeBar + " volume: " + volume);
        You should see output like the following:

        Begin OBU: CurrentBar: 1402 activeBar: 1401 volume: 308765
        End OBU: CurrentBar: 1402 activeBar: 1402 volume: 0
        Begin OBU: CurrentBar: 1403 activeBar: 1402 volume: 185323
        End OBU: CurrentBar: 1403 activeBar: 1403 volume: 0
        Begin OBU: CurrentBar: 1404 activeBar: 1403 volume: 137223
        The plots current value is being set to 0 at the end of OnBarUpdate, the SMA is looking at that current value when it reads your indicator. The resulting SMA value you see plotted is coming from the result of its math using a 0 value.

        Changing the indicator to instead set a current value other than 0 will allow the SMA to start calculating however that does change the general logic away from whats programmed in the BuySellVolume.

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

        Comment


          #5
          I can't seem to get this to work. The concept seems like it should be simple. Is there any way you could provide a quick example for how you'd accomplish this?

          Comment


            #6
            Hello swcooke,

            I had provided a sample of what I changed in post #2, the only thing I did differently was set a current value that is not 0:

            Code:
            if (CurrentBar != activeBar)
                        {
                            MyVolume[1] = volume; // change this line to MyVolume[0] = volume
                            volume = 0;
                            activeBar = CurrentBar;
                        }
            
                        MyVolume[0] = volume; // remove this line, its setting 0 to the plot
            This is only to make it see some data, that also does change how the indicator works so you would need to review how that change affects the values in contrast to what you are trying to do.

            This is simply to highlight what is happening, as noted the buy sell volume was not designed for a second series and by adding that you have introduced this problem in relation to how the indicator was originally intended to be used.


            I look forward to being of further assistance.



            JesseNinjaTrader Customer Service

            Comment


              #7
              I've adjusted my OnBarUpdate to what you've suggested however, now the Indicators values are 1 bar off. Also, the last bar does not seem to update once the state gets to real time. I've attached two scripts:

              1. MicrosoftVolumeJesse - This one is your suggestion but does not update the last bar in real time and no label shows. Also, the values are off by one bar when compared to volume indicator on MSFT.
              2. MicrosoftVolumeShawn - This is my best crack at it by making some changes.

              In either case, adding a SMA to either one of these results in some strange values. Just trying to understand how this works so I can apply it to my project.
              Attached Files

              Comment


                #8
                Hi Jesse,

                Just following up. Been playing with this but still cannot get this to work. The closest I have come is with my example. I am wondering if this has something to do with the fact that both the hosted and the hosting script must have the extra data series added and in the case of SMA, it doesn't. Is that the case here or should SMA actually work?

                Comment


                  #9
                  Hello swcooke,

                  I've adjusted my OnBarUpdate to what you've suggested however, now the Indicators values are 1 bar off. Also, the last bar does not seem to update once the state gets to real time.
                  Right, the BuySellVolume uses OnEachTick in a very specific way to plot the accumulation in realtime and to reset on the first tick of each new bar. It utilizes OnMarketData() which is called after OnBarUpdate() on realtime data. As such it is technically always one tick behind as OnBarUpdate() is called first and that is why we reset the Plot of the indicator for each first tick.

                  By making the changes I had shown that deviates from the original visual plotting logic but is what is needed to avoid the erroneous values when being used for input. This is simply to show what is happening but was not a complete solution or means to make that logic work with more than one series.

                  In the sample you are working with the plot is being set only when CurrentBar != activeBar which is part of the reason why the value is not updating in realtime. If you wanted to update the value in realtime you would need to do something similar to the buy sell volume where it updates the plot outside of the condition. For each tick you can update the current [0] BarsAgo plot value if you wanted to update the building bar values.

                  The reason for the delay of one bar is due to what plot value is being set. The buy sell volume sets the 1 BarsAgo plot value where in your sample we have modified to use the 0 BarsAgo. You could set the 1 BarsAgo value to correct that but then we are going back into the same problem surrounding the input not working with the SMA. the Current value needs to be set so the SMA can calculate.


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

                  Comment

                  Latest Posts

                  Collapse

                  Topics Statistics Last Post
                  Started by Waxavi, Today, 02:10 AM
                  0 responses
                  6 views
                  0 likes
                  Last Post Waxavi
                  by Waxavi
                   
                  Started by TradeForge, Today, 02:09 AM
                  0 responses
                  11 views
                  0 likes
                  Last Post TradeForge  
                  Started by Waxavi, Today, 02:00 AM
                  0 responses
                  2 views
                  0 likes
                  Last Post Waxavi
                  by Waxavi
                   
                  Started by elirion, Today, 01:36 AM
                  0 responses
                  4 views
                  0 likes
                  Last Post elirion
                  by elirion
                   
                  Started by gentlebenthebear, Today, 01:30 AM
                  0 responses
                  5 views
                  0 likes
                  Last Post gentlebenthebear  
                  Working...
                  X