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

Is it possible to combine different Bars in a Multi Time Frame & Instrument indicator

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

    Is it possible to combine different Bars in a Multi Time Frame & Instrument indicator

    Hello,

    I am trying to modify an indicator. The original indicator works with primary Range Bars and secondary Minute Bars. The secondary Bars object is added optionally.

    I added secondary Tick Bars. So now:

    BarsArray[0] is Range Bars,
    BarsArray[1] is Tick Bars,
    optionally I can add BarsArray[2] - it is Minute Bars.

    Now I have these errors:

    When I run the script with all three Bars, the Minute Bars is never processed. I check CurrentBars array and CurrentBars[2] is always -1.

    When I try to switch off Minute Bars or to run the script without Minute Bars, NinjaTrader goes to some undefined state - I don't see the chart and there are no messages in the output window.

    What could be the reason? Is there any incompatibility between different bars types?

    Thanks,

    Valentin

    #2
    Hello,

    Thank you for the question.

    There should not be a incompatibility, you are free to add whichever data series you need, this may be caused by the logic that is used in OnBarUpdate.

    In general when you see a index of -1, this usually means that the BarsInProgress for that series has not yet been run.

    Can you paste the section of OnBarUpdate where you are checking for CurrentBars?

    Most likely you will need to place a check returning if the bars are not yet there.

    For example one way would be

    if(CurrentBars[0] <1 || CurrentBars[1] <1) return;

    This would simply wait until the second series has at least 1 bar to use.

    After I see what your logic is like I would be able to determine what is happening.

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

    Comment


      #3
      Hello Jesse,

      Here is the code that I use to check the bars:

      Code:
      Print("CurrentBars[0] = " + CurrentBars[0]);
      Print("CurrentBars[1] = " + CurrentBars[1]);
      Print("CurrentBars[" + (BarsArray.Length - 1) + "] = " + CurrentBars[BarsArray.Length-1]);
      allBarsExist = true;
      for (barsIndex = 0; barsIndex < BarsArray.Length; barsIndex++)
      {
      	allBarsExist = allBarsExist && (CurrentBars[barsIndex] >= 0);
      }
      Print("!allBarsExist = " + !allBarsExist);
      When I run the script with all three bars, CurrentBars[0] and CurrentBars[1] increase, but CurrentBars[2] is always -1. I tested it with 1-minute bars and after 3 minutes it is still -1.

      But this is half of the problem. The indicator uses TickSize to call a function from OnStartUp. So I added Print() to check the value. Here is the code:

      Code:
      double tickSize = TickSize;
      this.pv = 1.0;
      Print("tickSize = " + tickSize);
      while (this.FracPortion(tickSize * this.pv) > 0.0)
      {
             this.pv *= 10.0;
      }
      I run the script with AAPL, primary bar is Range 4, 1st supplementary bar is Tick 89, second supplementary bar is 1 Minute.

      It reads "tickSize = 0.01" in Output window. This is AAPL's tick size.

      Then I run the script without minute bars. I expect to see either "tickSize = 0.01" or "tickSize = 89" in Output window, but there is nothing there.

      The script doesn't call this Print() in OnStartUp.

      It is the same when I try to run the script without minute bars from the beginning - the screen goes white, without chart, and without messages in Output window.

      Comment


        #4
        Hello,

        Thank you for providing that.

        I have made a simple example using the code you provided and was able to get it running.

        This required me to check that the CurrentBars index has a value before calculating anything which is the standard way to process a script when using multiple bar series.

        First I set up a Range chart, Next I used the following code to complete the test:

        Code:
        protected override void Initialize()
        {
        	Add(PeriodType.Tick, 1);
        	Add(PeriodType.Minute, 1);
        }
        
        private bool allBarsExist;
        private int barsIndex;
        
        protected override void OnBarUpdate()
        {
        	if(CurrentBars[0] < 1 || CurrentBars[1] < 1 || CurrentBars[2] < 1) return;
        			
        	Print("CurrentBars[0] = " + CurrentBars[0]);
        	Print("CurrentBars[1] = " + CurrentBars[1]);
        	Print("CurrentBars[" + (BarsArray.Length - 1) + "] = " + CurrentBars[BarsArray.Length-1]);
        	allBarsExist = true;
        	for (barsIndex = 0; barsIndex < BarsArray.Length; barsIndex++)
        	{
        		allBarsExist = allBarsExist && (CurrentBars[barsIndex] >= 0);
        	}
        	Print("!allBarsExist = " + !allBarsExist);
        }
        I did not test the second portion you had posted simply because this is using a while statement.

        while statements are very bad when used in a NinjaScript file, you do not want to stop the script from processing as this is meant to be a constantly updating script.
        If you use a while statement in OnBarUpdate, you are preventing the script from getting further updates and could potentially lock up the chart or freeze your platform.

        Instead I would recommend using logic to do your check instead of a while statement, OnBarUpdate will continue to be run so you can do the check over and over again in OnBarUpdate.

        I would recommend looking at the examples on the following pages as they explain more about using multi series scripts, CurrentBars and BarsInProgress. These are all fundamental when using multi series scripts and will likely be required from beginning to end with these type of scripts.







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

        Comment


          #5
          Thank you, Jesse.

          I simplified the check of CurrentBars. Then I commented everything after

          Code:
          Print("tickSize = " + tickSize);
          So all statements in OnBarUpdate after this Print() are commented (including the while loop). All statements in OnBarUpdate are commented too.

          I put a Print() in Initialize(), before to add the optional Bars.

          Here is the code:

          Code:
          Print(this.useSMAFilter);
          if (this.useSMAFilter)
          {
              Add(Instrument.FullName, PeriodType.Minute, 1);
          }
          These are the last lines in Initialize().

          I tested indicator again. Here is the output with useSMAFilter = true:

          True
          True
          True
          True
          tickSize = 0.01
          Indicator has 4 plots (and 4 values) and it seems that Initialize() is called 4 times. Is it true that Initialize() is called once for each plot?

          Then I tested with useSMAFilter = false. Here is output:

          True
          True
          True
          False
          It is strange that these values are different. I expected False, False, False, False.

          There is no tickSize. The script doesn't reach Print() in OnBarUpdate. The chart disappeared again.

          I also tested the script with useSMAFilter = false from the beginning. The output was

          True
          True
          False
          So only 3 values instead of 4.

          It seems that there is a problem with useSMAFilter = false and the script stops after the first 'false'.

          What could be the problem?

          Comment


            #6
            Hello,

            Thank you for the reply.

            Using prints in Initialize can be confusing and this is because Initialize will be called only once when you apply the script, but it will also be called every time you open the indicators panel as this controls what you are seeing in the indicator properties partially.

            The 3 trues you are seeing are most likely residual from opening the indicators list, you can do a couple of things here.

            at the top of your initialize you can add in
            ClearOutputWindow();

            This would ensure the output is cleared before your script runs in the chart, removing the prior prints.

            Second would be to check if the series is there by using BarsArray.Length, you would see 3 output if 3 series are present, otherwise 2 if there are only 2 etc.

            I am assuming the reason the script is stopping in OnBarUpdate, is that when you set your bool to false, it is no longer adding in that data series. If you are trying to print the dataseries or do anything with that index the script would not run because that index does not exist.

            It would be helpful if you attach the script in full so I could see the total logic, if you do not want to post the script publicly we can continue this through our support at [email protected]

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

            Comment


              #7
              Thank you, Jesse,

              I added ClearOutputWindow() in Initialize() before Print() and added Print(BarsArray.Length) in OnStartUp(). I will send indicator to [email protected].

              Comment


                #8
                Originally posted by Valyo View Post
                Thank you, Jesse.

                I simplified the check of CurrentBars. Then I commented everything after

                Code:
                Print("tickSize = " + tickSize);
                So all statements in OnBarUpdate after this Print() are commented (including the while loop). All statements in OnBarUpdate are commented too.

                I put a Print() in Initialize(), before to add the optional Bars.

                Here is the code:

                Code:
                Print(this.useSMAFilter);
                if (this.useSMAFilter)
                {
                    Add(Instrument.FullName, PeriodType.Minute, 1);
                }
                These are the last lines in Initialize().

                I tested indicator again. Here is the output with useSMAFilter = true:



                Indicator has 4 plots (and 4 values) and it seems that Initialize() is called 4 times. Is it true that Initialize() is called once for each plot?

                Then I tested with useSMAFilter = false. Here is output:



                It is strange that these values are different. I expected False, False, False, False.

                There is no tickSize. The script doesn't reach Print() in OnBarUpdate. The chart disappeared again.

                I also tested the script with useSMAFilter = false from the beginning. The output was



                So only 3 values instead of 4.

                It seems that there is a problem with useSMAFilter = false and the script stops after the first 'false'.

                What could be the problem?
                What are the errors in your log?

                Comment


                  #9
                  Hello,

                  I just wanted to update the thread with the outcome of what was happening regarding the chart freezing.

                  This is caused by toggling an Add() statement and refreshing the NinjaScript on the chart instead of actually removing the indicator from the chart and then re adding it.

                  The scenario is that a bool switch is used to toggle an Add statement.

                  If the data series is added everything works but if the user toggles the bool and the Add() statement is no longer used, this caused the chart to lock up because the data series collection was modified without actually removing and re adding the indicator to fully refresh all the series.

                  Please let me know if I may be of further assistance.
                  JesseNinjaTrader Customer Service

                  Comment


                    #10
                    There are no error messages. The chart just freezes with white screen.

                    Comment


                      #11
                      Hello Jesse,

                      OK, but why the chart freezes when I set bool switch to false from the beginning?

                      Valentin

                      Comment


                        #12
                        Hello,

                        I was unable to produce that from the initial add on the chart as it would not add the additional series at all being false. After switching from true to false I was able to get the chart to freeze because the chart refreshed but the indicator has not been removed and re added.

                        Either way this is not the correct way to allow a user to use the data series or not, in turn you would want to just add the series and remove the bool check, in your logic in OnBarUpdate you can allow the user to use this series or not using a bool.

                        the data series should not be used in this way as it causes a error when you do not fully remove and re add the indicator and would not be beneficial for the end user to have this action.

                        Please let me know if I may be of further assistance.
                        JesseNinjaTrader Customer Service

                        Comment


                          #13
                          OK, thank you. I will change the script so that the series is always added, and then will check for boolean value.

                          in OnBarUpdate you can allow the user to use this series or not using a bool.
                          Is there a specific property or method to allow the use of data series in OnBarUpdate?

                          You say that you couldn't produce the error from the initial add on the chart, but I still get this error. I hope that when I remove the condition from Add(), this error will disappear.

                          Comment


                            #14
                            Hello,

                            Yes once you remove that from the code, and then completely remove the indicator from the chart, press OK, open the indicators again and re add it, it will refresh the Initialize.

                            anytime you change Initialize it is recommended to just remove the indicator from the chart and re add it to ensure all the changes to Initialize are taken.

                            Is there a specific property or method to allow the use of data series in OnBarUpdate?
                            This would be your existing bool you are currently using in Initialize, just do not use this bool in Initialize and instead use it to determine the logic in OnBarUpdate or where ever else in the script it may be needed.

                            For example if you wanted the switch to control if the dataseries being used is from index 0 or index 1 you could do something as simple as the following:

                            Code:
                            double smaValue = 0;
                            if(boolVariable == true)
                            {
                            smaValue = SMA(Closes[0], 14)[0];
                            } else{
                            smaValue = SMA(Closes[1], 14)[0];
                            }
                            This would simply use the Second series instead of the first when the user changes the variable, this would not freeze the chart but would allow control over the series.

                            This is just a simple example but I hope this can show some basic logic to get you started, you will of course need to change some of your script to adapt to the change but ultimately this would be the best way to accomplish using a specific series depending on a user input bool value.

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

                            Comment

                            Latest Posts

                            Collapse

                            Topics Statistics Last Post
                            Started by ZenCortexCLICK, Today, 04:58 AM
                            0 responses
                            2 views
                            0 likes
                            Last Post ZenCortexCLICK  
                            Started by sidlercom80, 10-28-2023, 08:49 AM
                            172 responses
                            2,280 views
                            0 likes
                            Last Post sidlercom80  
                            Started by Irukandji, Yesterday, 02:53 AM
                            2 responses
                            17 views
                            0 likes
                            Last Post Irukandji  
                            Started by adeelshahzad, Today, 03:54 AM
                            0 responses
                            4 views
                            0 likes
                            Last Post adeelshahzad  
                            Started by Barry Milan, Yesterday, 10:35 PM
                            3 responses
                            13 views
                            0 likes
                            Last Post NinjaTrader_Manfred  
                            Working...
                            X