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

Problems with multi data series indicator

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

    Problems with multi data series indicator

    I have an indicator that has a secondary data series on the same symbol but larger time frame on a renko chart using AddRenko().

    This custom indicator preforms a series of calculations based on the close. When I apply and 8 Renk added series using AddRenko() to a 4 Renko chart, The values don't match a regular 8 Renko chart. Since I was using Close[0] in my code, I assumed it was reading closes from the 4 renko (base chart) instead of the added 8 Renko data series that was using add renko.

    I decided to create a Series<double> called dsClose to build a data set of closes on the added data series (8 Renko). When I did this, I started getting index errors like this:

    Code:
    Error on calling 'OnBarUpdate' method on bar 10: You are accessing an index with a value that is invalid since it is out-of-range. I.E. accessing a series [barsAgo] with a value of 5 when there are only 4 bars on the chart.
    I thought this was strange, since I was using dsClose.Count to get the upper bounds of the close data set. so I performed a test using the following code:

    int closeCount = 0;
    if (BarsInProgress == 1)
    {

    dsClose[0] = Closes[1][0];
    closeCount = closeCount + 1;
    Print("CC: " + closeCount.ToString() + " Closes " + dsClose.Count.ToString());
    }
    This resulted in the following:

    CC: 1 Closes 9830
    If I am firing the first iteration of BarsInProgress == 1 as demonstrated by closeCount having a value of 1, why would the dsClose object have a count of 9830 when it should only be 1?

    #2
    Hello MarthaClines,

    The custom series is synchronized to the primary series (the chart bars).

    Printing dsClose.Count will be the count of all of the primary bars on the chart (even before they are processed in historical data).
    Printing Closes[1].Count would give you the count of all of the secondary bars.

    Likely this is historical data and you are comparing the total number of historical primary bars (not CurrentBars[0] which is the currently processing bar for the primary series) to a custom counter that is incremented after the first secondary bar closes.
    Chelsea B.NinjaTrader Customer Service

    Comment


      #3
      Originally posted by NinjaTrader_ChelseaB View Post
      Hello MarthaClines,

      The custom series is synchronized to the primary series (the chart bars).

      Printing dsClose.Count will be the count of all of the primary bars on the chart (even before they are processed in historical data).
      Printing Closes[1].Count would give you the count of all of the secondary bars.

      Likely this is historical data and you are comparing the total number of historical primary bars (not CurrentBars[0] which is the currently processing bar for the primary series) to a custom counter that is incremented after the first secondary bar closes.
      I am really confused. So I modified the code as follows:

      if (BarsInProgress == 1)
      {

      double c = Close[0];
      dsClose[0] = c;


      closeCount = closeCount + 1;
      Print("CC: " + closeCount.ToString() + " Closes " + dsClose.Count.ToString());
      }
      and I am getting
      CC: 1 Closes 9953
      I only want the close at the time BarsInProgress == 1. How do I avoid pulling in historical data? Values should not be added to the dsClose series other than a single value of C obtained at the time.. yet it has 9,953 values … ;( I need to build a recordset (data series) of closes based on the secondary data not primary

      Comment


        #4
        Hello MarthaClines,

        To prevent historical data from being processed add

        if (State == State.Historical)
        return;

        To the top of OnBarUpdate().

        Below is a link to the help guide.
        https://ninjatrader.com/support/help...n-us/state.htm

        A series holds a value for every bar on the chart.

        dsClose is being assigned the value of Close[0] which is the close price (or current price) of the secondary series.

        dsClose[0] will only have one value for the most recent bar which will be equal to Close[0] (Closes[1][0]).

        dsClose[1] would be the value for the previous bar using a barsAgo value of 1, which will be equal to Closes[1][1].

        dsClose.Count is the number of bars (not the value of the last bar).
        Last edited by NinjaTrader_ChelseaB; 05-15-2019, 09:00 AM.
        Chelsea B.NinjaTrader Customer Service

        Comment


          #5
          I am going to need the historical data to calculate the indicator. I still cant figure out why dsClose has more values that it should. I created a new test that will hopefull shed some more light.

          The follow code is establishes class whide variables:

          private Series<double> dsClose;
          private int closeCount = 0;
          Then in the OnBarUpdate event I modified the (BarsInProgress == 1) test as follows:


          protected override void OnBarUpdate()
          {
          if (BarsInProgress == 1)
          {
          double c = Close[0];
          dsClose[0] = c;
          closeCount = closeCount + 1;

          double[] arrayBars = testGetBars(dsClose.Count, dsClose);

          return;
          }
          return;
          }
          I then created testGetBars to investigate the dsClose object as follows:



          private double[] testGetBars(int xCurrentBar, ISeries<double> xClose)
          {
          Print("enter TEST getBars " + "CurBar: " + xCurrentBar.ToString() + " Close COunt: " + xClose.Count.ToString());

          int num = xCurrentBar;
          if (num > 250)
          {
          num = 250;
          }
          double[] array = new double[num + 1];
          int num2 = 0;

          for (int i = 0; i != 250 ; i++)
          {
          Print("TEST I= " + i.ToString() + " CurrentBar: " + CurrentBar.ToString() + " Close Count: " + xClose.Count.ToString());
          Print("TEST xClose: " + xClose[i].ToString());

          array[num2++] = xClose[i];
          }
          return array;

          Print("exit get bars");
          }
          The result of the test is as follows:

          enter TEST getBars CurBar: 10134 Close COunt: 10134
          before For
          TEST I= 0 CurrentBar: 0 Close Count: 10134
          TEST xClose: 2887.75
          TEST I= 1 CurrentBar: 0 Close Count: 10134
          TEST xClose: 0
          TEST I= 2 CurrentBar: 0 Close Count: 10134
          TEST xClose: 0
          TEST I= 3 CurrentBar: 0 Close Count: 10134
          TEST xClose: 0
          TEST I= 4 CurrentBar: 0 Close Count: 10134
          TEST xClose: 0
          TEST I= 5 CurrentBar: 0 Close Count: 10134
          Indicator '': Error on calling 'OnBarUpdate' method on bar 4: You are accessing an index with a value that is invalid since it is out-of-range. I.E. accessing a series [barsAgo] with a value of 5 when there are only 4 bars on the chart.
          So from this test, getBars is being called from CurrentBar 0: which is the very last bar on the far right of chart - the bar that is most current. On this bar, the dsClose.Count has a value of 10134 - meaning there should be 10134 bars worth of closes. The for loop is reading the last 250 valus of the 10134. On the 5th bar back, I am getting an index out of range error.

          There are a couple of proplems with this.
          1. I should not be receiving an out of index error on index 5 if dsClose has 10134 bars. I have no idea why I am receiving this error
          2. At index 2, 3, and 4 - the value is Zero. dsClose is being populated inside
            (BarsInProgress == 1) if block, so it shouldnt have zeros. I need the close values of each seondary data series bar, without padding zeros when a primary bar forms but a secondary dosent - into a Series<double> object.


          Comment


            #6
            I have somewhat fixed the problem by passing the close into my indicators function, it is calculating - but the values of the Close are still wrong. On the attached screen shot, you can see I added a Renko 8 data series to the chart and linked the indicator (very last panel) to it. The indicator plots correctly because it is receiving the correct values for the close. The third panel from the bottom is the same indictor but using AddRenko to add a data series through code rather than to AddData Series panel. The indicators values and colors are wrong because incorrect close values passed into the indicator function when (BarsInProgress == 1).

            I am trying to create a strategy that uses multiple time frames based on my indicators. I am coding this indicator to confirm that I am getting correct values before I work on the strategy. In this image, I had a long signal at 1501 that would not have been taken because of the incorrect calculation. There is math not only in the values, but also in the direction that will be used to make the decision for buy, sell, or flat. Its very important that I get the correct close values.

            Click image for larger version

Name:	issuex2.png
Views:	682
Size:	1.13 MB
ID:	1057436
            Attached Files

            Comment


              #7
              Bumping the thread so this doesn't get lost/forgotten rather than creating a new thread

              Comment


                #8
                Hello MarthaClines,

                CurrentBar 0 is the first bar. This would be on the far left if you scrolled the chart as far left as it will go. CurrentBar is the currently processing bar number starting a 0. A value of 1 would be the second bar on the chart.

                Count is the total number of bars (starting at 1 because this is the number of bars). In historical data, this value will not change as each bar is processed.

                Try making a new script and in OnBarUpdate print CurrentBar and print Count. This will give you an idea of what each of these are for.

                Also below are links to the help guide.




                Also, attached is a simple example script that adds a renko series and prints the values for each bar to the output window.

                And a video that details how these values match the values on a chart.
                Attached Files
                Chelsea B.NinjaTrader Customer Service

                Comment


                  #9
                  Thanks Chelsea:

                  I am doing what you are doing and still having issues. I thought that it might be my custom renko bar, but I am getting the same issue on the renko bar that came with NT. I am attaching my script that I am using so you can see first hand what I am doing. Below is a link that demonstrates the issue.




                  Attached Files

                  Comment


                    #10
                    Hello MarthaClines,

                    I am not able to see any text in this video even when setting the quality to the maximum which is 360p.

                    Are you able to reproduce the behavior using the script I have provided you using the exact steps shown in the video?
                    If so, I want to test the script I have provided you on your end.
                    Please send an email to platformsupport [at] ninjatrader [dot] com. In the email please include a link to this forum thread.

                    I won't be able to assist with the custom bar type, but be sure you are able to reproduce using regular renko bars.
                    Chelsea B.NinjaTrader Customer Service

                    Comment


                      #11
                      Originally posted by NinjaTrader_ChelseaB View Post
                      Hello MarthaClines,

                      I am not able to see any text in this video even when setting the quality to the maximum which is 360p.

                      Are you able to reproduce the behavior using the script I have provided you using the exact steps shown in the video?
                      If so, I want to test the script I have provided you on your end.
                      Please send an email to platformsupport [at] ninjatrader [dot] com. In the email please include a link to this forum thread.

                      I won't be able to assist with the custom bar type, but be sure you are able to reproduce using regular renko bars.
                      I am getting closer to the problem. Using your script, I get the same issue. When I did the test in the video I forgot to compile the code on the NT native rinko … after doing so, its working.

                      So, I am getting correct closes using native renko but not my custom rinko bar -;( at least using the AddRenko() to add the data series. but when I add the data series to the chart (CNTRL + F) then link the indicator to it - all is also fine. It has something to do with my custom renko bar it appears.

                      I am at a loss on how to obtain these closes. Maybe I can add my secondary data series using CNTRL +F and write a scrit to export the closes to a XML and read them from my indicator? Is there a way to access data from a data series added to a chart with CNTRL+F?

                      Comment


                        #12
                        Hello MarthaClines,

                        Ctrl + f is the hotkey to open the Find window to search for text.

                        If you open a chart using the custom bar type, and in a new indicator print the Time[0] and Close[0] of each bar (without adding a secondary series), do the prints match the chart?
                        Chelsea B.NinjaTrader Customer Service

                        Comment


                          #13
                          Originally posted by NinjaTrader_ChelseaB View Post
                          Hello MarthaClines,

                          Ctrl + f is the hotkey to open the Find window to search for text.

                          If you open a chart using the custom bar type, and in a new indicator print the Time[0] and Close[0] of each bar (without adding a secondary series), do the prints match the chart?
                          Yes they match. The close seems to be different when I do an AddRenko on the custom bar type.

                          Comment


                            #14
                            Hello MarthaClines,

                            You can not use AddRenko() on a custom bar type. You must use AddDataSeries().

                            From the help guide:
                            2. You can add a custom BarsType which is installed on your system by casting the registered enum value for that BarsPeriodType. For example: AddDataSeries((BarsPeriodType)14, 10);
                            3. You can specify optional BarsPeriod values (such as Value2) of a custom BarsType in the BarsPeriod object initializer. For example: AddDataSeries(new BarsPeriod() { BarsPeriodType = (BarsPeriodType)14, Value = 10, Value2 = 20 });
                            Chelsea B.NinjaTrader Customer Service

                            Comment


                              #15
                              I have been working with your previous suggestion. It appears to sort of fix the problem. I removed the AddRenko() statement and replaced it with the following:

                              AddDataSeries(null, new BarsPeriod { BarsPeriodType = (BarsPeriodType)1995, Value = 8, Value2 = 3, BaseBarsPeriodValue = 50, MarketDataType = MarketDataType.Last});
                              I have closes that are correct, but only at the moment when BarsInProgress == 1, something is modiying the value when BarsInProgreess == 0. I created the following code that passes values into one of my function and performs tests. The code is as follows:


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

                              if (BarsInProgress == 1)
                              {
                              eCloseHolder = Closes[1][0];
                              extClose[0] = eCloseHolder;

                              double thTrend = 0;
                              double thHammer = 0;

                              jelTHExt(ref thTrend, ref thHammer, Closes[1], CurrentBar);

                              extHammer[0] = thHammer;
                              extTrend[0] = thTrend;

                              double tmpTHDir = 0;

                              if (extTrend[0] > extTrend[1])
                              {
                              tmpTHDir = 2;
                              if (extTrend[0] < 0) tmpTHDir = 1;
                              }

                              if (extTrend[0] < extTrend[1])
                              {
                              tmpTHDir = -2;
                              if (extTrend[0] > 0) tmpTHDir = -1;
                              }

                              if (tmpTHDir < 0) extDirTH[0] = -1;
                              if (tmpTHDir > 0) extDirTH[0] = 1;

                              Print("******************************************* **SECONDARY CLOSE: " + Closes[1][0].ToString() + "******************************************");
                              Print("************* TH-DIR: " + extDirTH[0].ToString());

                              }

                              if (BarsInProgress == 0)
                              {
                              Print(string.Format("{0} | BarsInProgress: {1} | CurrentBar {2} | Count: {3} | PrimaryClose: {4} | Secondary Close: {5} | CloseHolder: {6} | extTHDir: {7}",
                              Time[0], BarsInProgress, CurrentBar, Count, Close[0], extClose[0], eCloseHolder, extDirTH[0]));

                              }
                              The variable eCloseHolder is the actual correct close of the secondary series. This value is in the print statement in BarsInProgress == 1 using Closes[1][0] and in the print statement as eCloseHoder when BarsInProgress == 0.

                              During BarsInProgress == 1 I am assigning Closes[1][0] to eCloseHolder and getting the correct value, then adding that value to extCloses[0]. I am doing this to avoiding padding the extClose dataset with same close values each time the lower timeframe (BarsInProgress ==0) produces a close. A padded dataset will result in erroneous values from my functions. When you look at the image attached to this message, you can see that extCloses[0] is being altered for each BarsInProgress == 0. I don't understand why this is happening, because extCloses[0] is assigned only when BarsInProgress == 1. The value returned should be the same value as the closeholder - which is the correct value. I tried running Closes[1] into my function, hoping maybe it will be unpadded and with correct values - but my function is returning incorrect values. extTHDir should be 1 not -1.

                              So, in the image below, you will see 4 time stamps produced when BarsInProgress == 0. These 4 time stamps should all have the same secondary close of 2841 as shown by the closeholder variable.... meaning extClose[0] should be = to closeholder which is 2841. However extClose[1] should be 2840, the value of closeholder previously when BarsInProgress == 1. So starting at timestamp 3:54:53 and working backwards, extClose[0] should be 2841 and extClose[1] should be 2840.

                              I don't know how to explain it. I am trying to get a recordset of closes on a larger time frame (secondary) that is not padded with the same closes for each close of the smaller time frame, which is the primary time frame. In the code above, why would the value of extClose[0] change for each BarsInProgress ==0 when its value is assigned in BarsInProgress == 1? Maybe this might be a better way to ask the question?

                              You can also notice this with the extDirTH variable that is only assigned when BarsInProgress ==1, yet is has different values for each Subsequent BarsInProgress==0 for every single BarsInProgress == 1. This value, which is wrong at the moment, should be changing during BarsInProgress ==0 but it is.

                              Click image for larger version  Name:	issue3x.png Views:	1 Size:	1.23 MB ID:	1058044

                              Last edited by MarthaClines; 05-19-2019, 09:15 PM.

                              Comment

                              Latest Posts

                              Collapse

                              Topics Statistics Last Post
                              Started by kujista, Today, 05:44 AM
                              0 responses
                              5 views
                              0 likes
                              Last Post kujista
                              by kujista
                               
                              Started by ZenCortexCLICK, Today, 04:58 AM
                              0 responses
                              5 views
                              0 likes
                              Last Post ZenCortexCLICK  
                              Started by sidlercom80, 10-28-2023, 08:49 AM
                              172 responses
                              2,281 views
                              0 likes
                              Last Post sidlercom80  
                              Started by Irukandji, Yesterday, 02:53 AM
                              2 responses
                              18 views
                              0 likes
                              Last Post Irukandji  
                              Started by adeelshahzad, Today, 03:54 AM
                              0 responses
                              8 views
                              0 likes
                              Last Post adeelshahzad  
                              Working...
                              X