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

Multi-timeframe volumetric bar

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

    Multi-timeframe volumetric bar

    Hi, I have a problem with multi-timeframe volumetric bar. I have created an indicator that uses volumetric bar as shown below. Now my question is that how in a strategy I can call this indicator for multi-timeframes. Do I need to create a new series in the original indicator for every volumetric time series or I can just pass it from the strategy to indicator and get back the result? The strategy shown below does not do the job. I appreciate any help. Thank you.

    ----------------------INDICATOR---------------------------
    public class AAforNinjaTrader1 : Indicator
    protected override void OnBarUpdate()
    {
    NinjaTrader.NinjaScript.BarsTypes.VolumetricBarsTy pe barsType = Bars.BarsSeries.BarsType as
    NinjaTrader.NinjaScript.BarsTypes.VolumetricBarsTy pe;
    if (barsType == null)
    return;
    bidVol[0] = barsType.Volumes[CurrentBar].GetBidVolumeForPrice(Close[0]) ;
    }
    [Browsable(false)]
    [XmlIgnore]
    public Series<double> bidVol
    {
    get { return Values[0]; }
    }
    -----------------------------------------------------------
    -------------------------STRATEGY--------------------
    public class ABforNinjaTrader1 : Strategy
    {
    private NinjaTrader.NinjaScript.Indicators.AAforNinjaTrade r1 AAforNinjaTrader11;
    private NinjaTrader.NinjaScript.Indicators.AAforNinjaTrade r1 AAforNinjaTrader12;

    else if (State == State.Configure)
    {
    AddVolumetric(null, BarsPeriodType.Range, 2, VolumetricDeltaType.BidAsk, 1); //Time series 1
    AddVolumetric(null, BarsPeriodType.Range, 4, VolumetricDeltaType.BidAsk, 1); //Time series 2
    }
    else if (State == State.DataLoaded)
    {
    AAforNinjaTrader11 = AAforNinjaTrader1(Close[???]); // I do not know how to initialize for Time series 1
    AAforNinjaTrader12 = AAforNinjaTrader1(Close[???]); // I do not know how to initialize for Time series 2
    }

    protected override void OnBarUpdate()
    {
    if (BarsInProgress == 1)
    Print( AAforNinjaTrader11.bidVol[0]); // I would like to see the result for the Time series 1
    // return;

    if (BarsInProgress == 2) // I would like to see the result for the Time series 2
    Print( AAforNinjaTrader12.bidVol[0]);
    return;
    }
    -----------------------------------------------------------







    #2
    Hello Photon66,

    From the given use that looks correct how you call the indicator from the BarsInProgress 1 and 2, are you getting incorrect results or what is the problem you are having? You shouldn't need to pass a specific series to the indicator in DataLoaded because you are calling it from the designated series in each BarsInProgress.

    If you are trying to compare this against manually added indicators, you may want to instead try using AddChartIndicator from the strategy for this type of test.

    I noticed you also passed null in for the instrument of AddVolumetric, I would suggest trying to use a specific instrument here as well. AddVolumetric("MSFT"


    I look forward to being of further assistance.

    JesseNinjaTrader Customer Service

    Comment


      #3
      Hi Jesse, Thank you for the reply. Please ignore my previous post as I think the following explains better my problem. In the indicator and strategy below that I have created, I would like to make references to an indicator for different time frames (e.g. default range 2, and added ranges 4, and 6). I know I can use (BarsInProgress == 0) or (BarsInProgress == 1) to calculate the indicator for different time frame but that does not help me here.

      What I would like to do is to compare all the indicators of the different time frames within (BarsInProgress == 0). For example

      if (BarsInProgress == 0){
      if (indicator for range default > 100 && indicator for range 4 >50 && indicator for range 6 > 400) {
      do something
      }
      }


      My problem is highlighted with red in the bottom of the strategy below. Thank you.



      =============================
      public class AAforNinjaTrader1 : Indicator
      {
      protected override void OnStateChange()
      {
      if (State == State.SetDefaults)
      {
      Description = @"Enter the description for your new custom Indicator here.";
      Name = "AAforNinjaTrader1";
      Calculate = Calculate.OnEachTick;
      ....

      }
      else if (State == State.DataLoaded)
      {
      ClearOutputWindow();
      }

      else if (State == State.Configure)
      {
      }
      }

      protected override void OnBarUpdate()
      {
      NinjaTrader.NinjaScript.BarsTypes.VolumetricBarsTy pe barsType = Bars.BarsSeries.BarsType as
      NinjaTrader.NinjaScript.BarsTypes.VolumetricBarsTy pe;
      if (barsType == null)
      return;

      bidVol[0] = barsType.Volumes[CurrentBar].GetBidVolumeForPrice(Close[0]) ;
      }


      ================================================== ============

      {
      public class ABforNinjaTrader1 : Strategy
      {
      private NinjaTrader.NinjaScript.Indicators.AAforNinjaTrade r1 AAforNinjaTrader11;

      #region StateChange
      protected override void OnStateChange()
      {
      if (State == State.SetDefaults)
      {
      Description = @"Enter the description for your new custom Strategy here.";
      Name = "ABforNinjaTrader1";
      Calculate = Calculate.OnEachTick;
      EntriesPerDirection = 1;
      ....
      }
      else if (State == State.Configure)
      {
      AddVolumetric(null, BarsPeriodType.Range, 4, VolumetricDeltaType.BidAsk, 1);
      AddVolumetric(null, BarsPeriodType.Range, 6, VolumetricDeltaType.BidAsk, 1);
      }
      else if (State == State.DataLoaded)
      {
      ClearOutputWindow();
      AAforNinjaTrader11 = AAforNinjaTrader1(Closes[0]);
      AAforNinjaTrader12 = AAforNinjaTrader1(Closes[1]);

      }
      }
      #endregion


      #region BarUpdate

      protected override void OnBarUpdate()
      {

      if (CurrentBars[0] < 1)
      return;

      if (BarsInProgress == 0){
      if (AAforNinjaTrader11.bidVol[0] > 100 && indicator for range 4 >50 && indicator for range 6 > 400
      ){ //don't know how to implement AAforNinjaTrader11.bidVol for other time frames
      Print("Yes");
      }
      return;}

      ================================================== =========



      Comment


        #4
        Hello Photon66,

        From the sample you provided this would likely be best consolidated into the strategy so you can correctly reference BarsArray for each added volumetric series. If you do this from the indicator you would also need to one of the following.
        Add the data you want to use there
        use the indicator by calling the indicator in the correct BarsInProgress
        use the indicators Input PriceSeries sample and use priceSeries.PriceType.Bars.BarsType property. https://ninjatrader.com/support/help...lightsub=input

        If you choose to skip the indicator and place this in the strategy you would just use the BarsArray directly like the help guide sample shows.

        Code:
        NinjaTrader.NinjaScript.BarsTypes.VolumetricBarsType barsType = BarsArray[1].BarsType as
        NinjaTrader.NinjaScript.BarsTypes.VolumetricBarsType;



        You could then access those variables from BarsInProgress 0 to calculate them all at the same time.


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

        Comment


          #5
          Hello Jesse, Thank you very much for the reply. I have difficulties connecting all the dots in your reply as I am not very experienced with NT and C# . From what I could put together from your post I came up with the following which does not seem to work correctly, although it does not give any errors either. I appreciate if you could correct my mistakes. My main chart is volumetric with range 2 and I would like to add volumetric range 4 and 6 for further analysis on top. Thank you.


          ================================================== ==============
          public class AAforNinjaTrader1 : Indicator
          ...
          {
          protected override void OnBarUpdate()
          {
          NinjaTrader.NinjaScript.BarsTypes.VolumetricBarsTy pe barsType = Bars.BarsSeries.BarsType as
          NinjaTrader.NinjaScript.BarsTypes.VolumetricBarsTy pe;


          bidVol[0] = barsType.Volumes[CurrentBar].GetBidVolumeForPrice(Close[0]) ;
          Print("From Indicator " + Time[0]+ " | " + CurrentBar + " ------ " +bidVol[0]);
          }
          ================================================== ==============
          public class ABforNinjaTrader1 : Strategy
          {
          private NinjaTrader.NinjaScript.Indicators.Amir.AAforNinja Trader1 AAforNinjaTrader10;
          private NinjaTrader.NinjaScript.Indicators.Amir.AAforNinja Trader1 AAforNinjaTrader11;
          private NinjaTrader.NinjaScript.Indicators.Amir.AAforNinja Trader1 AAforNinjaTrader12;

          ...
          }
          else if (State == State.Configure)
          {
          AddVolumetric(null, BarsPeriodType.Range, 4, VolumetricDeltaType.BidAsk, 1);
          AddVolumetric(null, BarsPeriodType.Range, 6, VolumetricDeltaType.BidAsk, 1);
          }
          else if (State == State.DataLoaded)
          {
          ClearOutputWindow();

          PriceSeries priceSeries2 = Inputs[1] as PriceSeries;
          PriceSeries priceSeries3 = Inputs[2] as PriceSeries;

          AAforNinjaTrader10 = AAforNinjaTrader1(Closes[0]);
          AAforNinjaTrader11 = AAforNinjaTrader1(Inputs[1]);
          AAforNinjaTrader12 = AAforNinjaTrader1(Inputs[2]);

          }
          }

          protected override void OnBarUpdate()
          {

          if (CurrentBars[0] <1)
          return;

          if (BarsInProgress == 0){ \\Would like to be able to calculate other timeframes paramters within BarsInProgress == 0
          Print( "Main timeframe range=2" + " , " + Times[0] + " , " + CurrentBar + " , " + AAforNinjaTrader10.bidVol[0]); \\Printing the indicator calculation from main chart timeframe range 2
          Print("Added timeframe range=4" + " , "+ Times[0] + " , " + CurrentBars[1] + " , " + + AAforNinjaTrader11.bidVol[0]); \\Printing the indicator calculation from added timeframe range 4
          Print("Added timeframe range=6" + " , "+ Times[0] + " , " + CurrentBars[2] + " , " + + AAforNinjaTrader12.bidVol[0]); \\Printing the indicator calculation from added timeframe range 6
          return;}

          if (BarsInProgress == 1){
          Print( "Timeframe range=4" + " , " + Times[0] + " , "+ CurrentBar + " , " + AAforNinjaTrader10.bidVol[0]); \\Printing the indicator calculation from added timeframe range 4
          return;}

          if (BarsInProgress == 2){
          Print( "Timeframe range=4" + " , " + Times[0] + " , "+ CurrentBar + " , " + AAforNinjaTrader10.bidVol[0]); \\Printing the indicator calculation from added timeframe range 6
          return;
          ================================================== ==============

          Comment


            #6
            Hello Photon66,

            The first thing I want to mention here is that I believe you should use better naming for the test indicators, you have a circular dependency here. AAforNinjaTrader1 should not be calling its self. I am not certain if that was a mistake but you may want to use easier names like HostIndicator and ChildIndicator. This is what I am talking about:

            Code:
            AAforNinjaTrader10 = AAforNinjaTrade[B]r1[/B](Closes[0]);
            AAforNinjaTrader11 = AAforNinjaTrade[B]r1[/B](Inputs[1]);
            AAforNinjaTrader12 = AAforNinjaTrade[B]r1[/B](Inputs[2]);

            To make this a little more simple to explain I am going to make reference below as the Host indicator and Child indicator.

            The Input syntax would be if you wanted to utilize the volumetric data like shown in the help guide sample from within your ChildIndicator. That would not be used in the HostIndicator.

            If you are trying to pass the volumetric bars, BarsArray[0],[1].[2] as an input to your ChildIndicator, the ChildIndicator would need to make use of "Input" in its logic so you can cast to the Volumetric type like the help guide Volumetric sample.

            That would like the following in the ChildIndicator

            Code:
            PriceSeries priceSeries = Inputs[0] as PriceSeries;
            NinjaTrader.NinjaScript.BarsTypes.VolumetricBarsType barsType = priceSeries.Bars.BarsType as NinjaTrader.NinjaScript.BarsTypes.VolumetricBarsType;
            In the parent indicator where you call the ChildIndicator you would then need to pass in a volumetric series:

            ChildIndicator myChild1 = ChildIndicator(BarsArray[1]);

            As long as you used Input in the ChildIndicator you could make use of that BarsArray you passed in from within the ChildIndicator.






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

            Comment


              #7
              Hi Jesse, Thank you very much for very helpful comments. Based on your post I improved (I think!) my codes; however, it still does not work. The indicator seems to work correctly, but not the strategy and how it calls the indicator. I appreciate if you could tell me what is wrong. Thank you.

              ===============Indicator========================
              public class AANT : Indicator
              {
              protected override void OnStateChange()
              {
              if (State == State.SetDefaults)
              {
              Name = "AANT";
              Calculate = Calculate.OnEachTick;
              }

              protected override void OnBarUpdate()
              {
              PriceSeries priceSeries = Inputs[0] as PriceSeries;
              NinjaTrader.NinjaScript.BarsTypes.VolumetricBarsTy pe barsType = priceSeries.Bars.BarsType as NinjaTrader.NinjaScript.BarsTypes.VolumetricBarsTy pe;

              if (barsType == null)
              return;

              bidVol[0] = barsType.Volumes[CurrentBar].GetBidVolumeForPrice([0]) ;
              }

              ===============Strategy========================

              public class AB : Strategy
              {
              private NinjaTrader.NinjaScript.Indicators.AANT myChild1;
              private NinjaTrader.NinjaScript.Indicators.AANT myChild2;
              private NinjaTrader.NinjaScript.Indicators.AANT myChild3;

              protected override void OnStateChange()
              {
              if (State == State.SetDefaults)
              {
              Name = "AB";
              Calculate = Calculate.OnEachTick;
              }
              else if (State == State.Configure)
              {

              AddVolumetric(null, BarsPeriodType.Range, 4, VolumetricDeltaType.BidAsk, 1);
              AddVolumetric(null, BarsPeriodType.Range, 6, VolumetricDeltaType.BidAsk, 1);
              }
              else if (State == State.DataLoaded)
              {
              }
              }
              protected override void OnBarUpdate()
              {

              if (CurrentBars[0] <1 || CurrentBars[1] <1 ||CurrentBars[2] <1 )
              return;
              AANT myChild1 = AANT(BarsArray[0]);
              AANT myChild2 = AANT(BarsArray[1]);
              AANT myChild3 = AANT(BarsArray[2]);

              myChild1 = AANT(BarsArray[0]);
              myChild2 = AANT(BarsArray[1]);
              myChild3 = AANT(BarsArray[2]);

              if (BarsInProgress == 0){

              Print( "Main timeframe range=2" + " , " + Times[0] + " , " + CurrentBars[0] + " , " + myChild1.bidVol[0]);

              Print("Added timeframe range=4" + " , " + Times[1] + " , " + CurrentBars[1] + " , " + myChild2.bidVol[0]);

              Print("Added timeframe range=6" + " , " + Times[2] + " , " + CurrentBars[2] + " , " + myChild3.bidVol[0]);
              return;}
              }
              ================================================== ==================

              Comment


                #8
                Hello Photon66,

                From the given details I am not certain what would be wrong as I cannot see what you were comparing against. Are you seeing the prints not match or what is the problem?

                To make this more simple you could try removing the indicator from the equation for the time being to check that you get the correct values in the strategy. The strategy is already adding the data so if the indicator is simply re-plotting the following value:

                barsType.Volumes[CurrentBar].GetBidVolumeForPrice(Close[0]) ;

                You could do this from the strategy instead to confirm that is working as you expected before passing the data to the indicator.

                I look forward to being of further assistance.

                JesseNinjaTrader Customer Service

                Comment


                  #9
                  Hello Jesse,

                  Thank you again for checking out my codes and good comments. I could not figure out what the source of the errors are. There is no compilation error, only execution error. I attach two screenshots when the indicator works stand alone correctly and the log of the errors I see when I run the strategy. My guess is that my indicator initializations are not correct. Should they be in the OnBarUpdate() or State.Configure or State.DataLoaded. I also attach the original indicator and strategy codes. Thank you.
                  Attached Files

                  Comment


                    #10
                    Hello

                    Thank you for the additional detail.

                    It looks like this is due to using BarsArray rather than Closes for the input, bars array is not seen as a Price series it would appear. You can either change the strategy and pass Closes[1] etc.. or change the indicator to read the BarsArray which would be:

                    Code:
                    NinjaTrader.Data.Bars priceSeries = Inputs[0] as NinjaTrader.Data.Bars;
                    NinjaTrader.NinjaScript.BarsTypes.VolumetricBarsType barsType = priceSeries.BarsType as NinjaTrader.NinjaScript.BarsTypes.VolumetricBarsType;

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

                    Comment


                      #11
                      [Edited] Hello Jesse, Thank you very much for the reply. Your suggested change in the code seems to solve the error problems.

                      The only problem I see is that when my chart time setting is exactly the same as my added time frames the output of the indicator is not the same for all. To be more precise if I add the following strategy to a range 6 volumetric chart and add two range 6 volumetric time series on top of that I get different results:

                      ==============Strategy
                      ....
                      else if (State == State.Configure)
                      {

                      AddVolumetric(null, BarsPeriodType.Range, 6, VolumetricDeltaType.BidAsk, 1); // Added time series
                      AddVolumetric(null, BarsPeriodType.Range, 6, VolumetricDeltaType.BidAsk, 1); // Added time series


                      }
                      }

                      protected override void OnBarUpdate()
                      {

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

                      AANT myChild0 = AANT(Closes[0]);
                      AANT myChild1 = AANT(Closes[1]);
                      AANT myChild2 = AANT(Closes[2]);
                      myChild0 = AANT(Closes[0]);
                      myChild1 = AANT(Closes[1]);
                      myChild2 = AANT(Closes[2]);

                      Print(" ----------------------- " + BarsInProgress);

                      Print( "Main timeframe range=6" + " , " + Times[0][0] + " , " + CurrentBars[0] + " , " + myChild0.bidVol[0]);
                      Print("Added timeframe range=6" + " , " + Times[1][0] + " , " + CurrentBars[1] + " , " + myChild1.bidVol[0]);
                      Print("Added timeframe range=6" + " , " + Times[2][0] + " , " + CurrentBars[2] + " , " + myChild2.bidVol[0]);

                      ========================= The first few lines of the output:

                      ----------------------- 1
                      Main timeframe range=6 , 2/16/2021 6:33:22 PM , 38 , 22
                      Added timeframe range=6 , 2/16/2021 6:33:22 PM , 1 , 1
                      Added timeframe range=6 , 2/16/2021 6:33:22 PM , 1 , 1
                      ----------------------- 2
                      Main timeframe range=6 , 2/16/2021 6:33:22 PM , 38 , 22
                      Added timeframe range=6 , 2/16/2021 6:33:22 PM , 1 , 1
                      Added timeframe range=6 , 2/16/2021 6:33:22 PM , 1 , 1
                      ----------------------- 1
                      Main timeframe range=6 , 2/16/2021 6:33:22 PM , 38 , 22
                      Added timeframe range=6 , 2/16/2021 6:33:22 PM , 1 , 1
                      Added timeframe range=6 , 2/16/2021 6:33:22 PM , 1 , 1
                      ----------------------- 2
                      Main timeframe range=6 , 2/16/2021 6:33:22 PM , 38 , 22
                      Added timeframe range=6 , 2/16/2021 6:33:22 PM , 1 , 1
                      Added timeframe range=6 , 2/16/2021 6:33:22 PM , 1 , 1
                      ----------------------- 1
                      Main timeframe range=6 , 2/16/2021 6:33:22 PM , 38 , 22
                      Added timeframe range=6 , 2/16/2021 6:33:22 PM , 1 , 2
                      Added timeframe range=6 , 2/16/2021 6:33:22 PM , 1 , 2
                      ----------------------- 2
                      Main timeframe range=6 , 2/16/2021 6:33:22 PM , 38 , 22
                      Added timeframe range=6 , 2/16/2021 6:33:22 PM , 1 , 2
                      Added timeframe range=6 , 2/16/2021 6:33:22 PM , 1 , 2
                      ----------------------- 1
                      Main timeframe range=6 , 2/16/2021 6:33:22 PM , 38 , 22
                      Added timeframe range=6 , 2/16/2021 6:33:22 PM , 1 , 2
                      Added timeframe range=6 , 2/16/2021 6:33:22 PM , 1 , 2
                      ----------------------- 2
                      Main timeframe range=6 , 2/16/2021 6:33:22 PM , 38 , 22
                      Added timeframe range=6 , 2/16/2021 6:33:22 PM , 1 , 2
                      Added timeframe range=6 , 2/16/2021 6:33:22 PM , 1 , 2
                      ....
                      ============================================
                      As we can see the main chart is not the same as the added time series. I appreciate your comment.



                      Last edited by Photon66; 02-16-2021, 06:12 PM.

                      Comment


                        #12
                        Hello Photon66,

                        Its possible that you are seeing a difference due to the loading of the series during market hours. For any tick based comparison I would suggest to start the script prior to the session start and then play forward into the session to check if they match. You could try using the playback connection here to make sure there are no discrepancies for starting the scripts. If that is not the solution could you attach a .cs file of the script you used so I can try that on my end?

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

                        Comment


                          #13
                          Thank you very much for the reply.

                          Comment

                          Latest Posts

                          Collapse

                          Topics Statistics Last Post
                          Started by fx.practic, 10-15-2013, 12:53 AM
                          5 responses
                          5,406 views
                          0 likes
                          Last Post Bidder
                          by Bidder
                           
                          Started by Shai Samuel, 07-02-2022, 02:46 PM
                          4 responses
                          98 views
                          0 likes
                          Last Post Bidder
                          by Bidder
                           
                          Started by DJ888, Yesterday, 10:57 PM
                          0 responses
                          8 views
                          0 likes
                          Last Post DJ888
                          by DJ888
                           
                          Started by MacDad, 02-25-2024, 11:48 PM
                          7 responses
                          160 views
                          0 likes
                          Last Post loganjarosz123  
                          Started by Belfortbucks, Yesterday, 09:29 PM
                          0 responses
                          9 views
                          0 likes
                          Last Post Belfortbucks  
                          Working...
                          X