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

Add indicator to other indicator in NT8

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

    #16
    All right thanks for the steps and great help Jim!

    I'll do the work tomorrow.

    You have a great night-day!

    Talk tomorrow.

    Be well!

    Comment


      #17
      Hi Jim,

      I got the
      Input Series set to default,
      the
      Plot on chart unchecked,
      the
      Value Plot set to Prior High and Prior Open as you detailed,
      and the
      Plot on chart unchecked.

      Thanks a lot!

      Screenshot:

      Click image for larger version

Name:	NVIDIA_Share_AKscIfclXu.png
Views:	233
Size:	681.1 KB
ID:	1163953

      Once you get the same code generated with the print, test the strategy and observe the value in the NinjaScript output window.

      A video of the working prints:

      https://drive.google.com/file/d/14yIWUxqBvgm1w0rAjuquc6dD8RlykeCb/view?usp=sharing

      Then implement that code in an indicator and test the same.
      Implementation of The Strategy Builder Code into The Indicator Code Video:

      https://drive.google.com/file/d/1in1-Czjno__VJn5oBdKKlBx1A_06NKoh/view?usp=sharing

      The next step is adding a plot to the indicator and assigning the value to the plot instead of printing it.

      Adding the Plot code to the Indicator Video:

      https://drive.google.com/file/d/1Q6eKjCDuettEXUys46YULDrUHZmsQI3A/view?usp=sharing

      (ADDED AT THE END OF THE if (State == State.SetDefaults) SCOPE/PARENTHESIS)

      AddPlot(Brushes.White, "Diff");

      (ADDED AT THE END OF THE if (State == State.SetDefaults) SCOPE/PARENTHESIS)

      Value[0] = (PriorDayOHLC1.PriorHigh[0] - (PriorDayOHLC1.PriorOpen[0]));

      (ADDED AT THE END OF THE public class HighMinusOpen1 : Indicator)

      #region Properties
      [Browsable(false)]
      [XmlIgnore]
      public Series<double> Diff
      {
      get { return Values[0]; }
      }
      #endregion

      You can then add it to the Market Analyzer as an indicator column, and ensure that you have your plot selected in the Market Analyzer Column.

      For now the Market analyzer returns zero, as in the chart's plot for yesterday Friday 16/07/2021 time 16:00:00 as example.

      Screenshot:
      Click image for larger version

Name:	NVIDIA_Share_8X5ZIM6fjD.png
Views:	191
Size:	770.3 KB
ID:	1163955


      The day prior yesterday, Thursday 15/07/2021 was indeed a day where High = Open, so the indicator is working, returning the Diff. as zero.

      Screenshot:

      Click image for larger version

Name:	NVIDIA_Share_7OlZBfN8Nf.png
Views:	198
Size:	79.2 KB
ID:	1163957

      The Market Analyzer Screenshot:

      Click image for larger version

Name:	NVIDIA_Share_qf845GyPW8.png
Views:	178
Size:	679.7 KB
ID:	1163959
      Thank a lot Jim! You rock!

      I'll do some more testing and be back if needed later.

      Have a good one.

      Be well!
      Attached Files

      Comment


        #18
        Hi Jim,

        I've done some more tests and got this result:

        This Prints code returns 1.47 instead of -0.33 for yesterday 16/07/2021:

        Code:
        Print(Time[0] +" " + Convert.ToString((PriorDayOHLC1.PriorOpen[0] - (PriorDayOHLC1.PriorClose[0])) ));
        Click image for larger version  Name:	NVIDIA_Share_UvPA126B1u.png Views:	0 Size:	805.6 KB ID:	1163966

        Why isn't it returning -0.33, instead of 1.47?

        What next to do to make it do the correct math?


        Second question:

        How does it work on Mondays? I need the Prior Friday's values on Mondays, not the Sundays ones.

        And I don't need the Prior Friday's values on Saturdays.

        Nor the Prior Saturday's values on Sundays.

        Does it auto adjust or do we need to adjust the code? If so how the simplest way?

        I have a google sheets code for that (With weekdays 1 to 7 = Sunday (1) to Saturday (7)):
        Code:
        =IFS(
        [B]WEEKDAY(A5,1)=7,"",
        WEEKDAY(A5,1)=1,"",[/B]
        [B]WEEKDAY(A5,1)=2,A5-3,[/B]
        WEEKDAY(A5,1)=3,A5-1,
        WEEKDAY(A5,1)=4,A5-1,
        WEEKDAY(A5,1)=5,A5-1,
        WEEKDAY(A5,1)=6,A5-1)

        On Saturdays (Weekday # 7) -> return nothing:

        WEEKDAY(A5,1)=7,"",


        On Sundays (Weekday #1) -> return nothing:

        WEEKDAY(A5,1)=1,"",


        On Mondays (Weekday #2) -> Take today's ( running date/ today() ) date (in cell A5) and subtract 3 (3 days) to get prior Friday's date and values:

        WEEKDAY(A5,1)=2,A5-3

        How to achieve the same result the simplest way?
        Attached Files
        Last edited by Cormick; 07-17-2021, 05:41 AM.

        Comment


          #19
          Hello Cormick,

          PriorDayOHLC calculates from intra day data and does not read daily bars. It will need to be added to an intraday chart/data series.

          A Chart/Data Series created with an ETH (default) Trading Hours template will have Sunday as the prior session on Monday while an RTH session will have Friday as the prior session on Monday.

          You can either choose to apply the script to an RTH data series, or you can use logic that checks the 1 more BarsAgo on Monday for PriorOpen[BarsAgo] and PriorHigh[BarsAgo].

          Also ensure that when creating the Data Series when configuring the indicator in the Market Analyzer, there is enough days to load to account for weekends/holidays. Holidays are automatically filtered from the data series following the Trading Hours template.

          If you need to create logic that checks the Day Of Week so you can apply a different plot value for that day, the Strategy Builder can help you to see how to write that syntax. (See attached screenshot.)
          Attached Files
          Last edited by NinjaTrader_Jim; 07-19-2021, 02:31 PM.
          JimNinjaTrader Customer Service

          Comment


            #20
            Hi Jim,

            Thanks for the answer.

            Was that the answer to the 0.33, instead of 1.47 result question?

            PriorDayOHLC calculates from intra day data and does not read daily bars. It will need to be added to an intraday chart/data series.
            If it was, I used a 60 min chart on the bottom right of the screenshot of post #18. So should it work since it's an intraday chart/data series?
            If so why doesn't it work?
            And what to do next to make it work?

            And beside, I won't be using it on a chart. I need it for display in the Market analyzer.

            How to make it work for the Market Analyzer?

            I'll study your second answer thanks a lot.


            EDIT1 (question #1):

            I think I found what you pointed at in quote above.
            Do you mean under Time frame > Load data based on:
            Bars instead of Days?
            I had it set to Days before.
            I attached a Market Analyzer screenshot below.

            EDIT2 (question #1):

            Ok, I had it Load 240 60min bars (10 days).
            Now it's returning a 0.03 as value in the Market Analyzer instead of the prior zero, thanks!
            2nd screenshot attached.

            Now I need to work out the proper prior day problem.
            I'll see what I can do with custom logic solution.
            Back as soon as progresses made.

            EDIT3 (question #2):

            Ok, I've launched a new Strategy builder and replicated your Condition screenshot settings.
            With the 'Time series selected on the left (3rd screenshot)
            I get the error 'Type of left expression and right expression do not match, please select similar expressions.'

            No error when selecting 'Date series' instead of 'Time series' (4th screenshot).
            The view code output:
            if (Times[0][0].DayOfWeek == DayOfWeek.Monday)




            Is the Date series the right to use?

            I'll see what similar coding to my google sheets example I can achieve and be back asap thanks!


            EDIT4 (question #2):

            Ok, I've come up with the following code following your
            you can use logic that checks the 1 more BarsAgo on Monday for PriorOpen[BarsAgo] and PriorHigh[BarsAgo]
            directions.

            if (Times[0][0].DayOfWeek != DayOfWeek.Monday)
            {
            Value[0] = PriorDayOHLC1.PriorOpen[0] - (PriorDayOHLC1.PriorClose[0]);
            }
            else
            {
            Value[0] = PriorDayOHLC1.PriorOpen[1] - (PriorDayOHLC1.PriorClose[1]);
            }

            I think it should work as is. I used Prior Open and Close instead to double check.

            I'll test now and come back with the result.


            EDIT5 (questions #1 & #2):

            Ok, I tested the code and the result is not as expected.

            It returns 0.03 in the Market Analyzer.
            But when checking against the actual Prior Friday's Open-Close result (71.48-71.81 = -0.33) it does not match.

            What's causing the mismatch?

            How to solve it the simplest way?

            I attached screenshot #4 for my settings:

            Click image for larger version  Name:	vmplayer_V7FNDx37GE.png Views:	0 Size:	642.6 KB ID:	1164189

            And the full code:
            Attached Files
            Last edited by Cormick; 07-19-2021, 01:16 PM.

            Comment


              #21
              Hello Cormick,

              In post #18, you are comparing the Daily High and Open of the current daily bar and not the prior daily bar. Additionally, the indicator is calculated from intraday data (controlled by the Trading Hours template of Data Series,) not daily bars, so this is not an apples to apples comparison. However, if you subtract the open of the prior bar from the high of the prior bar on your daily chart, you will see a similar result. See my attached screenshots.

              If you want to compare daily bars instead, you can add an additional data series and compare those values instead of using the PriorDayOHLC indicator. (This is possible with the Strategy Builder.) The biggest thing to note is that the intraday calculation does not have a settlement price for the daily close and is merely the last price traded at the session's close. Since you are comparing Open and High this is not as important.

              I also meant to use Date Series in my screenshot, which you have figured out. I will be correcting my screenshot for clarification in the thread.




              Attached Files
              Last edited by NinjaTrader_Jim; 07-19-2021, 02:33 PM.
              JimNinjaTrader Customer Service

              Comment


                #22
                Hi Jim,

                Thanks for the pointers and screenshots!

                In post #18, you are comparing the Daily High and Open of the current daily bar and not the prior daily bar.
                Yes I did not notice that thanks! I inferred from the output window's latest Prints it was the Prior day since the latest Prints were dated 16/07/2021, and I expected the indicator not to print/return values for the current day (last Friday at the time). but I noticed I also pointed at the last candle on the vis-ŕ-vis Daily chart and that should have let me know otherwise. Thanks!

                Additionally, the indicator is calculated from intraday data (controlled by the Trading Hours template of Data Series,) not daily bars, so this is not an apples to apples comparison.
                Ok, thanks for that info. I did not grasp the distinction beforehand. Thanks!

                However, if you subtract the open of the prior bar from the high of the prior bar on your daily chart, you will see a similar result. See my attached screenshots.

                ...

                The biggest thing to note is that the intraday calculation does not have a settlement price for the daily close and is merely the last price traded at the session's close. Since you are comparing Open and High this is not as important.
                Oh, yes.
                High minus Open are unique values (no last session vs settlement 2 values like the close),
                and from your previous quote snippet now I understand that the Close from the template (Intraday Chart) is different from the settlement Close (Daily Chart).

                Did you intend to share the 19/07/2021 Daily Chart screenshot instead of the 16/07/21 as your 2nd screenshot? — it shows 71.56 as the Close Price.
                Is the 1st screenshot the intraday Close for the 19/07/2021? — it shows 66.43 as the Close Price.
                And the Daily chart's close for the 19/07/2021 is 66.35.

                Click image for larger version  Name:	NVIDIA_Share_jL1SjuAgye.png Views:	0 Size:	605.6 KB ID:	1164278

                So a (0.43-0.35 =) -0.08 difference between the last session Close and the Settlement Close for the 19/07/2021.


                If you want to compare daily bars instead, you can add an additional data series and compare those values instead of using the PriorDayOHLC indicator. (This is possible with the Strategy Builder.)
                Thanks for that great suggestion. I've made progresses by understanding how adding multiple plots to an indicator must be done (which was not obvious from scanning the PriorDayOHLC indicator's multiple plots statements), from this post https://ninjatrader.com/support/foru...575#post777575.

                I had to understand I needed to change

                the
                Value[0] = PriorDayOHLC1.PriorOpen[0] - (PriorDayOHLC1.PriorClose[0]);

                to
                Values[0][0] = PriorDayOHLC1.PriorOpen[0];
                Values[1][0] = PriorDayOHLC1.PriorHigh[0];
                Values[2][0] = PriorDayOHLC1.PriorLow[0];
                Values[3][0] = PriorDayOHLC1.PriorClose[0];

                //Value[0] = PriorDayOHLC1.PriorOpen[0] - (PriorDayOHLC1.PriorClose[0]);
                Values[4][0] = Values[0][0] - (Values[3][0]);

                Now the code is working from the PriorDayOHLC indicator:

                Click image for larger version  Name:	NVIDIA_Share_aBkZA2EY9c.png Views:	0 Size:	1.15 MB ID:	1164279


                OnStateChange() Updated Code:
                Code:
                 protected override void OnStateChange()
                {
                if (State == State.SetDefaults)
                {
                Description = @"Enter the description for your new custom Indicator here.";
                Name = "HighMinusOpen1";
                Calculate = Calculate.OnBarClose;
                IsOverlay = false;
                DisplayInDataBox = true;
                DrawOnPricePanel = true;
                DrawHorizontalGridLines = true;
                DrawVerticalGridLines = true;
                PaintPriceMarkers = true;
                ScaleJustification = NinjaTrader.Gui.Chart.ScaleJustification.Right;
                //Disable this property if your indicator requires custom values that cumulate with each new market data event.
                //See Help Guide for additional information.
                IsSuspendedWhileInactive = true;
                AddPlot(Brushes.White, "PriorOpen");
                AddPlot(Brushes.Lime, "PriorHigh");
                AddPlot(Brushes.Red, "PriorLow");
                AddPlot(Brushes.Pink, "PriorClose");
                AddPlot(Brushes.Cyan, "OpenMinusClose");
                }
                else if (State == State.Configure)
                {
                }
                else if (State == State.DataLoaded)
                {
                PriorDayOHLC1 = PriorDayOHLC(Close);
                }
                }

                OnBarUpdate() and #region Properties Updated Code:
                Code:
                 protected override void OnBarUpdate()
                {
                if (BarsInProgress != 0)
                return;
                
                if (CurrentBars[0] < 1)
                return;
                
                // Set 1
                Print(Time[0] +
                " " + "Open Value: " + Convert.ToString(PriorDayOHLC1.PriorOpen[0]) +
                " " + "High Value: " + Convert.ToString(PriorDayOHLC1.PriorHigh[0]) +
                " " + "Low Value: " + Convert.ToString(PriorDayOHLC1.PriorLow[0]) +
                " " + "Close Value: " + Convert.ToString(PriorDayOHLC1.PriorClose[0]));
                {
                }
                
                
                if (Times[0][0].DayOfWeek != DayOfWeek.Monday)
                {
                Values[0][0] = PriorDayOHLC1.PriorOpen[0];
                Values[1][0] = PriorDayOHLC1.PriorHigh[0];
                Values[2][0] = PriorDayOHLC1.PriorLow[0];
                Values[3][0] = PriorDayOHLC1.PriorClose[0];
                
                //Values[4][0] = PriorDayOHLC1.PriorOpen[0] - (PriorDayOHLC1.PriorClose[0]);
                Values[4][0] = Values[0][0] - (Values[3][0]);
                }
                else
                {
                Values[0][0] = PriorDayOHLC1.PriorOpen[1];
                Values[1][0] = PriorDayOHLC1.PriorHigh[1];
                Values[2][0] = PriorDayOHLC1.PriorLow[1];
                Values[3][0] = PriorDayOHLC1.PriorClose[1];
                
                //Values[4][0] = PriorDayOHLC1.PriorOpen[0] - (PriorDayOHLC1.PriorClose[0]);
                Values[4][0] = Values[0][0] - (Values[3][0]);
                }
                
                }
                #region Properties
                [Browsable(false)]
                [XmlIgnore]
                public Series<double> PriorOpen
                {
                get { return Values[0]; }
                }
                
                [Browsable(false)]
                [XmlIgnore]
                public Series<double> PriorHigh
                {
                get { return Values[1]; }
                }
                
                [Browsable(false)]
                [XmlIgnore]
                public Series<double> PriorLow
                {
                get { return Values[2]; }
                }
                
                [Browsable(false)]
                [XmlIgnore]
                public Series<double> PriorClose
                {
                get { return Values[3]; }
                }
                
                [Browsable(false)]
                [XmlIgnore]
                public Series<double> OpenMinusClose
                {
                get { return Values[4]; }
                }
                #endregion


                Full code:


                Is it the right approach? Or is there some elements I missed about the PriorDayOHLC method that would potentially cause issues I'm not aware of?

                I'll next try adding a data series for the Daily bar to check the differences.


                I also meant to use Date Series in my screenshot, which you have figured out. I will be correcting my screenshot for clarification in the thread.
                Ok, thanks for confirming. I was not sure it was correct way and it worked!

                Attached Files

                Comment


                  #23
                  Hi Jim,

                  Back about my
                  I'll next try adding a data series for the Daily bar to check the differences.
                  I created a new indicator 'myDailyBarsOHLC'.

                  And used the same code but with the usual OHLC series below:

                  if (Times[0][0].DayOfWeek != DayOfWeek.Monday)
                  {
                  Values[0][0] = Open[1];
                  Values[1][0] = High[1];
                  Values[2][0] = Low[1];
                  Values[3][0] = Close[1];

                  //Values[4][0] = Open[1] - (Close[1]);
                  Values[4][0] = Values[0][0] - (Values[3][0]);
                  }
                  else
                  {
                  Values[0][0] = Open[0];
                  Values[1][0] = High[0];
                  Values[2][0] = Low[0];
                  Values[3][0] = Close[0];

                  //Values[4][0] = Open[0] - (Close[0]);
                  Values[4][0] = Values[0][0] - (Values[3][0]);
                  }
                  OnStateChange() Updated Code:
                  Code:
                  namespace NinjaTrader.NinjaScript.Indicators
                  {
                  public class myDailyBarsPriorOHLC : Indicator
                  {
                  //private PriorDayOHLC PriorDayOHLC1;
                  
                  protected override void OnStateChange()
                  {
                  if (State == State.SetDefaults)
                  {
                  Description = @"Enter the description for your new custom Indicator here.";
                  Name = "myDailyBarsPriorOHLC";
                  Calculate = Calculate.OnBarClose;
                  IsOverlay = false;
                  DisplayInDataBox = true;
                  DrawOnPricePanel = true;
                  DrawHorizontalGridLines = true;
                  DrawVerticalGridLines = true;
                  PaintPriceMarkers = true;
                  ScaleJustification = NinjaTrader.Gui.Chart.ScaleJustification.Right;
                  //Disable this property if your indicator requires custom values that cumulate with each new market data event.
                  //See Help Guide for additional information.
                  IsSuspendedWhileInactive = true;
                  AddPlot(Brushes.White, "PriorOpen");
                  AddPlot(Brushes.Lime, "PriorHigh");
                  AddPlot(Brushes.Red, "PriorLow");
                  AddPlot(Brushes.Pink, "PriorClose");
                  AddPlot(Brushes.Cyan, "OpenMinusClose");
                  }
                  else if (State == State.Configure)
                  {
                  }
                  else if (State == State.DataLoaded)
                  {
                  //PriorDayOHLC1 = PriorDayOHLC(Close);
                  }
                  }
                  OnBarUpdate() and #region Properties Updated Code:
                  Code:
                   protected override void OnBarUpdate()
                  {
                  if (BarsInProgress != 0)
                  return;
                  
                  if (CurrentBars[0] < 1)
                  return;
                  
                  // Set 1
                  Print(Time[0] +
                  " " + "Open Value: " + Convert.ToString(Open[1]) +
                  " " + "High Value: " + Convert.ToString(High[1]) +
                  " " + "Low Value: " + Convert.ToString(Low[1]) +
                  " " + "Close Value: " + Convert.ToString(Close[1]));
                  {
                  }
                  
                  
                  if (Times[0][0].DayOfWeek != DayOfWeek.Monday)
                  {
                  Values[0][0] = [B]Open[1];[/B]
                  Values[1][0] = [B]High[1];[/B]
                  Values[2][0] = [B]Low[1];[/B]
                  Values[3][0] = [B]Close[1];[/B]
                  
                  //Values[4][0] =[B] Open[1] - (Close[1]);[/B]
                  Values[4][0] = [B]Values[0][0] - (Values[3][0]);[/B]
                  }
                  else
                  {
                  Values[0][0] = [B]Open[0];[/B]
                  Values[1][0] = [B]High[0];[/B]
                  Values[2][0] = [B]Low[0];[/B]
                  Values[3][0] = [B]Close[0];[/B]
                  
                  //Values[4][0] = [B]Open[0] - (Close[0]);[/B]
                  Values[4][0] = [B]Values[0][0] - (Values[3][0]);[/B]
                  }
                  
                  }
                  #region Properties
                  [Browsable(false)]
                  [XmlIgnore]
                  public Series<double> PriorOpen
                  {
                  get { return Values[0]; }
                  }
                  
                  [Browsable(false)]
                  [XmlIgnore]
                  public Series<double> PriorHigh
                  {
                  get { return Values[1]; }
                  }
                  
                  [Browsable(false)]
                  [XmlIgnore]
                  public Series<double> PriorLow
                  {
                  get { return Values[2]; }
                  }
                  
                  [Browsable(false)]
                  [XmlIgnore]
                  public Series<double> PriorClose
                  {
                  get { return Values[3]; }
                  }
                  
                  [Browsable(false)]
                  [XmlIgnore]
                  public Series<double> OpenMinusClose
                  {
                  get { return Values[4]; }
                  }
                  #endregion
                  Full Code:
                  https://pastebin.com/HG3MPgzS


                  It is returning the same OHLC (and the Open[1] - Close[1] subtraction result) as the Daily Chart as intended:

                  Click image for larger version  Name:	NVIDIA_Share_UfdvZs59OT.png Views:	0 Size:	998.0 KB ID:	1164305


                  Is the code all right as is or do you see potential issues?

                  Do I still need the .DataLoaded below?

                  else if (State == State.DataLoaded)
                  {
                  //PriorDayOHLC1 = PriorDayOHLC(Close);
                  }

                  Also, I 'm not sure about the 'Mondays to Prior Fridays instead of Prior Sundays issue' what to index the OHLC with in the OnBarUpdate() Else statement.

                  On post #19 https://ninjatrader.com/support/foru...54#post1164154
                  above you said
                  you can use logic that checks the 1 more BarsAgo on Monday for PriorOpen[BarsAgo] and PriorHigh[BarsAgo].
                  So do I just need to index it to 2 like this?

                  if (Times[0][0].DayOfWeek != DayOfWeek.Monday)
                  {
                  Values[0][0] = Open[1];
                  Values[1][0] = High[1];
                  Values[2][0] = Low[1];
                  Values[3][0] = Close[1];

                  //Values[4][0] = Open[1] - (Close[1]);
                  Values[4][0] = Values[0][0] - (Values[3][0]);
                  }
                  else
                  {
                  Values[0][0] = Open[2];
                  Values[1][0] = High[2];
                  Values[2][0] = Low[2];
                  Values[3][0] = Close[2];

                  //Values[4][0] = Open[2] - (Close[2]);
                  Values[4][0] = Values[0][0] - (Values[3][0]);
                  }


                  Or is there other things to take into account to make it work as intended also on Mondays?
                  Attached Files
                  Last edited by Cormick; 07-20-2021, 10:00 AM.

                  Comment


                    #24
                    Hello Cormick,

                    There is a lot of information here in order to keep the thread concise, I have bulleted some notes regarding your last two posts.
                    1. My example screenshots in post #21 note the High minus the Open of the daily candle vs. what is plotted from the indicator. The indicator is plotting the PriorHigh minus the PriorOpen from PriorDayOHLC. We can see the minute chart shows the difference calculated from the indicator and the daily chart with the crosshairs over the previous daily bar shows the daily High and daily Open from the previous day's daily bar.
                    2. Your code from post #22 is using the the PriorDayOHLC indicator to get daily OHLC values (the indicator calculated from intraday data and not daily bars)
                    3. Your code from post #23 is not using the PriorDayOHLC indicator to get daily OHLC values, it is just getting the OHLC of the processing bar in the indicator. If the indicator is applied to a daily chart, it would be fetching daily OHLC values.
                    4. Your highlighted changes to BarsAgo indexes will have the indicator give you prior bar values, but you would not be referencing daily bars if the indicator is applied to something other than a daily chart
                    5. When you are making BarsAgo references, always make sure you have allowed the script o process that many bars before making that BarsAgo reference
                    Making sure there are enough bars in the data series you are processing - https://ninjatrader.com/support/help...nough_bars.htm

                    For more detail on working with BarsAgo indexes, see here - https://ninjatrader.com/support/help...ice_series.htm

                    If you want to learn more about adding additional data to a script and working with that added data, see here - https://ninjatrader.com/support/help...nstruments.htm

                    You may also use the Strategy Builder to create syntax for referencing additional data by adding a data series in the Additional Data tab, and then you may create conditions that reference that added data series in Conditions and Actions.
                    JimNinjaTrader Customer Service

                    Comment


                      #25
                      Hi Jim,

                      On further testing, I changed the OHLC indices from [0] to [2] and [1] of the OnBarUpdate() Else Statement:
                      Code:
                       else
                      {
                      Values[0][0] = Open[1];
                      Values[1][0] = High[1];
                      Values[2][0] = Low[1];
                      Values[3][0] = Close[1];
                      
                      //Values[4][0] = Open[1] - (Close[1]);
                      Values[4][0] = Values[0][0] - (Values[3][0]);
                      And I found out that it was the OnBarUpdate() Else Statement that was executing, not the 1st part (the if statement):
                      Code:
                      if (Times[0][0].DayOfWeek != DayOfWeek.Monday)
                      {
                      Values[0][0] = Open[1];
                      Values[1][0] = High[1];
                      Values[2][0] = Low[1];
                      Values[3][0] = Close[1];
                      
                      //Values[4][0] = Open[1] - (Close[1]);
                      Values[4][0] = Values[0][0] - (Values[3][0]);
                      }
                      It suggests that the OHLC index [0] was/is the correct index for the Prior Day's OHLC values.

                      Why is that so? Isn't the index zero applying the current bar/day OHLC, which would mean today's and not yesterday's values?

                      Why does index [1] return the OHLC Values of 2 days ago and not of 1 day ago?

                      The 2 relevant screenshots:

                      With

                      else
                      {
                      Values[0][0] = Open[0];
                      Values[1][0] = High[0];
                      Values[2][0] = Low[0];
                      Values[3][0] = Close[0];

                      //Values[4][0] = Open[0] - (Close[0]);
                      Values[4][0] = Values[0][0] - (Values[3][0]);
                      Click image for larger version

Name:	NVIDIA_Share_UfdvZs59OT.png
Views:	158
Size:	998.0 KB
ID:	1164321

                      with


                      else
                      {
                      Values[0][0] = Open[1];
                      Values[1][0] = High[1];
                      Values[2][0] = Low[1];
                      Values[3][0] = Close[1];

                      //Values[4][0] = Open[1] - (Close[1]);
                      Values[4][0] = Values[0][0] - (Values[3][0]);
                      Click image for larger version

Name:	NVIDIA_Share_OJVkKaJxn5.png
Views:	158
Size:	859.4 KB
ID:	1164322

                      Why isn't the else if statement working as intended?
                      We are Tuesday, so Times[0][0] IS NOT DayOfWeek.Monday, and therefore it should execute the if statement ( do X; ), not the Else stament ( do Y; ).
                      But it executes instead the Else statement ( do Y; ) since it is the Else statement's OHLC indexes update that changes the Prior Day.

                      if (Times[0][0].DayOfWeek != DayOfWeek.Monday)
                      {
                      // do X;
                      }

                      else
                      {
                      // do Y;
                      }


                      There is something I don't grasp about this behavior.
                      I checked the C# If Else documentation here: https://www.w3schools.com/cs/cs_conditions.php
                      What change do I need to make with the If Else statement?
                      Attached Files

                      Comment


                        #26
                        Hello Cormick,

                        We need to be aware of the Calculate mode and how it works in relation to historical data, realtime data, and bar indexes.

                        I suggest the following to fully grasp that:
                        1. In a new test indicator, print out the OHLC values of the processing bar (BarsAgo 0) in addition to the timestamp of the bar (Time[0],) the current bar index (CurrentBar) and the current State of the script (State) I have an example print included here.
                        2. Open a chart and enable the Data Box, then right click and select Show Bar Indexes and Show BarsAgo indexes
                        3. Then open the NinjaScript Output window and apply the indicator to the chart
                        4. Use the cross hair to see the CurrentBar index in the Data Box and compare it to the Output window, also comparing the OHLC and bar timestamps.
                        5. Retest with Calculate set to OnPriceChange/OnEachTick and OnBarClose
                        Example print:
                        Code:
                        Print(String.Format("CurrentBar index: {0} Time[0]: {1} Open[0]: {2}, High[0]: {3} Low[0]: {4}, Close[0]: {5} State: {6} Calculate: {7}", CurrentBar, Time[0], Open[0], High[0], Low[0], Close[0], State, Calculate));
                        You will see that with Calculate set to OnBarClose, OnBarUpdate is processed once on the close of a bar, and the BarsAgo 0 values represent the bar that has just closed which should not be confused with the developing bar.

                        If Calculate is set to OnPriceChange or OnEachTick, you can note that historical processing still follows updates similar to OnBarClose, but realtime updates will have OnBarUpdate process for the developing bar until it closes. This is because there is no intrabar movement with historical processing. Tick Replay can be used for historical OnEachTick/OnPriceChange, but this is a topic I would recommend opening a new thread on.

                        NinjaTrader uses the first tick of a new bar to signal when a bar has closed. If using Calculate.OnEachTick/OnPriceChange, you can check for the first tick of a new bar and make a BarsAgo reference of 1 to check the bar that has just closed. See the snippet in the documentation page below for an example.

                        IsFirstTickOfBar - https://ninjatrader.com/support/help...ttickofbar.htm

                        As for understanding how if/else statements evaluate, we recommend using prints outside of the condition that show what the values in the condition are, so you may see why it evaluates to true/false and why the code would take the if or else branch.
                        JimNinjaTrader Customer Service

                        Comment


                          #27
                          Originally posted by NinjaTrader_Jim View Post
                          Hello Cormick,

                          There is a lot of information here in order to keep the thread concise, I have bulleted some notes regarding your last two posts.
                          1. My example screenshots in post #21 note the High minus the Open of the daily candle vs. what is plotted from the indicator. The indicator is plotting the PriorHigh minus the PriorOpen from PriorDayOHLC. We can see the minute chart shows the difference calculated from the indicator and the daily chart with the crosshairs over the previous daily bar shows the daily High and daily Open from the previous day's daily bar.
                          2. Your code from post #22 is using the the PriorDayOHLC indicator to get daily OHLC values (the indicator calculated from intraday data and not daily bars)
                          3. Your code from post #23 is not using the PriorDayOHLC indicator to get daily OHLC values, it is just getting the OHLC of the processing bar in the indicator. If the indicator is applied to a daily chart, it would be fetching daily OHLC values.
                          4. Your highlighted changes to BarsAgo indexes will have the indicator give you prior bar values, but you would not be referencing daily bars if the indicator is applied to something other than a daily chart
                          5. When you are making BarsAgo references, always make sure you have allowed the script o process that many bars before making that BarsAgo reference
                          Making sure there are enough bars in the data series you are processing - https://ninjatrader.com/support/help...nough_bars.htm

                          For more detail on working with BarsAgo indexes, see here - https://ninjatrader.com/support/help...ice_series.htm

                          If you want to learn more about adding additional data to a script and working with that added data, see here - https://ninjatrader.com/support/help...nstruments.htm

                          You may also use the Strategy Builder to create syntax for referencing additional data by adding a data series in the Additional Data tab, and then you may create conditions that reference that added data series in Conditions and Actions.
                          Hi Jim,

                          Thanks for the details and answer.

                          1. My example screenshots in post #21 note the High minus the Open of the daily candle vs. what is plotted from the indicator. The indicator is plotting the PriorHigh minus the PriorOpen from PriorDayOHLC. We can see the minute chart shows the difference calculated from the indicator and the daily chart with the crosshairs over the previous daily bar shows the daily High and daily Open from the previous day's daily bar.
                          https://ninjatrader.com/support/foru...tch?id=1164196
                          https://ninjatrader.com/support/foru...tch?id=1164197
                          Ok. Thanks. I did not pay enough attention/noticed the indicator plot of 0.83 value in the Minute chart.
                          Then, 72.04 - 71.21 = 0.83 on the Daily Chart. Which make the values Intraday and Daily equal.
                          Since we are using the High minus the Open. (not the Intraday Close and settlement Close) — make sense, thanks a lot!


                          1. Your code from post #22 is using the the PriorDayOHLC indicator to get daily OHLC values (the indicator calculated from intraday data and not daily bars)
                          Yes, that was still the PriorDayOHLC one.

                          1. Your code from post #23 is not using the PriorDayOHLC indicator to get daily OHLC values, it is just getting the OHLC of the processing bar in the indicator. If the indicator is applied to a daily chart, it would be fetching daily OHLC values.
                          Yes. It will only works as intended if before use I preset the Market analyzer Data Series > Type = Days and Value = 1.
                          Otherwise it would fetch the prior OHLC of whatever Timeframe candle is selected (on the chart or Market Analyzer).
                          1. Your highlighted changes to BarsAgo indexes will have the indicator give you prior bar values, but you would not be referencing daily bars if the indicator is applied to something other than a daily chart
                          Yes, that compels the use of the indicator to needing the daily chart/Days and 1 in Market analyzer. But I did not think it was possible to use special Series/BarsPeriod (besides the OHLC) for the context. Thanks to you last post I've found about the BarsPeriods (more below), thanks!


                          1. When you are making BarsAgo references, always make sure you have allowed the script o process that many bars before making that BarsAgo reference

                            Making sure there are enough bars in the data series you are processing - https://ninjatrader.com/support/help...nough_bars.htm
                          On the Columns setting of the Market Analyzer window, I used 10 days for each call of OHLC and OpenMinusClose plot/value.

                          Click image for larger version  Name:	NVIDIA_Share_DFATh6HQtu.png Views:	0 Size:	663.2 KB ID:	1164352

                          Here are my Bars checks:
                          protected override void OnBarUpdate()
                          {
                          if (BarsInProgress != 0)
                          return;

                          if (CurrentBars[0] < 1)
                          return;

                          I'm not sure I grasp it right:
                          What you say is that in context I should make sure the minimum Bars loaded on the chart/taken into account by the Market Analyzer should be >= to at least 2 (the current day and the day before) to return valid Prior Day OHLC?

                          And from the Script part, the Indicator should be set to load at least also 2 (daily) bars?

                          So I should set it that way instead?
                          if (CurrentBars[0] < 2)
                          return;

                          For more detail on working with BarsAgo indexes, see here - https://ninjatrader.com/support/help...ice_series.htm
                          Ok. Thanks for that reference. I just learned about the Input for the Referencing Series section. I'll check it later.

                          If you want to learn more about adding additional data to a script and working with that added data, see here - https://ninjatrader.com/support/help...nstruments.htm
                          Great, thanks! I just learned about BarsPeriods!
                          https://ninjatrader.com/support/help...nstruments.htm
                          https://ninjatrader.com/support/help...arsperiods.htm
                          https://ninjatrader.com/support/help...barsperiod.htm
                          That was the missing piece! I thought up to that point you could not use custom Periods since I did not find them in the strategy Builder under Conditions and Actions > Time > Time series.
                          Why are the Bars Periods under additional data only? Shouldn't it make more sense to add them too under Conditions and Actions > Time > Time series?

                          Also, why is the AddDataSeries() method set inside the State.Configure() and not the OnBarUpdate() method?
                          I assume it is because the Period series must be 'pre-loaded (be in the State.Configure()) — configured— before the indicator can Update correctly?

                          For my current use, with the example from https://ninjatrader.com/support/help...arsperiods.htm

                          protected override void OnStateChange()
                          {
                          if (State == State.Configure)
                          {
                          // Adds a 5-minute Bars object to the strategy and is automatically assigned
                          // a Bars object index of 1 since the original data the strategy is ran on,
                          // set by the UI, takes the index of 0.
                          AddDataSeries("AAPL", BarsPeriodType.Minute, 5);
                          }
                          }

                          protected override void OnBarUpdate()
                          {
                          // Print out 5, the value of the secondary bars object
                          if (BarsInProgress == 1)
                          Print(BarsPeriods[1].Value);
                          }

                          You may also use the Strategy Builder to create syntax for referencing additional data by adding a data series in the Additional Data tab, and then you may create conditions that reference that added data series in Conditions and Actions.
                          From your directions with the Strategy Builder and Additional Data pointer (1st time I use it):

                          The Additional Data process:

                          Click image for larger version  Name:	NVIDIA_Share_jeOPC3alfE.png Views:	0 Size:	909.0 KB ID:	1164355

                          What does the "Use primary Instrument" mean?
                          Tip 4 on the AddDataSeries() doc page states:
                          https://ninjatrader.com/support/help...dataseries.htm
                          4. For the instrument name parameter null could be passed in, resulting in the primary data series instrument being used.
                          I just tested and it leaves it blank:
                          Click image for larger version  Name:	NVIDIA_Share_YlQ2MoD0LG.png Views:	0 Size:	902.4 KB ID:	1164357

                          I would like to have the Instrument changeable/not hard coded" so that I can apply the indicator to any instrument. Is that the use for the "Primary instrument" checkbox?

                          The Price series Process (adding The Open - Close comparison):

                          Click image for larger version  Name:	NVIDIA_Share_kBZqDDDDXi.png Views:	0 Size:	720.5 KB ID:	1164356

                          Thanks a lot for the Additional Data suggestion and all the other pointers! I'll test a way to use it tomorrow!

                          Talk later.

                          Be well!
                          Attached Files
                          Last edited by Cormick; 07-20-2021, 01:03 PM.

                          Comment


                            #28
                            Hello Cormick,

                            This thread is getting very full of information and will be difficult for others viewing the forums to follow. Admittedly, I am getting a bit of information overload with what we have already discussed.

                            We will ask that any questions that are separate from the original question of plotting the difference of two indicator plots in a new indicator be presented in new threads, only including the information relevant to your question. This not only helps users reading the forum, but helps us to better answer your questions, and if a technician is out of the office, then another technician will be able to step in.

                            Thanks for your understanding.

                            To conclude the thread and answer the questions already given here...

                            With regards to understanding CurrentBar checks and making sure the script has processed X number of bars before making BarsAgo references of X bars, this will be best understood after testing and observing how the bar indexes work in general. Testing what I have outlined in my last message will make this clear. You will see that the script starts processing from bar 0 in the data series it is applied to, and you cannot reference BarsAgo 2 when the script is processing bar 1 because there is no bar before bar 0.

                            Additional data must be added before the script starts processing data. OnBarUpdate will be processed then for each data series added. The Strategy Builder adds a check for BarsInProgress to ensure only data is processed on the primary data series. As you are working with unlocked scripts and additional data, it is highly important that you review the Multi Time Frame and Instruments documentation in full to understand the in's and out's of working with a multi time frame/multi instrument script.

                            The Use Primary Instrument checkbox tells NinjaTrader to use a different overload to add data to the script. You can read more about what "Method Overloading" is by researching publicly available C# resources on the topic. The different overloads are included in the AddDataSeries documentation. Using null as the instrument name tells NinjaTrader to use the primary data series instrument, as does using an overload that does not specify an instrument.

                            As mentioned, this thread is starting to become off topic and difficult to follow with all of the information here. Going forward, please open new threads with specific questions, and only the detail relevant to that question in each thread so we can answer more directly and keep the information shared easy to follow for others.
                            JimNinjaTrader Customer Service

                            Comment


                              #29
                              Originally posted by NinjaTrader_Jim View Post
                              Hello Cormick,

                              We need to be aware of the Calculate mode and how it works in relation to historical data, realtime data, and bar indexes.

                              I suggest the following to fully grasp that:
                              1. In a new test indicator, print out the OHLC values of the processing bar (BarsAgo 0) in addition to the timestamp of the bar (Time[0],) the current bar index (CurrentBar) and the current State of the script (State) I have an example print included here.
                              2. Open a chart and enable the Data Box, then right click and select Show Bar Indexes and Show BarsAgo indexes
                              3. Then open the NinjaScript Output window and apply the indicator to the chart
                              4. Use the cross hair to see the CurrentBar index in the Data Box and compare it to the Output window, also comparing the OHLC and bar timestamps.
                              5. Retest with Calculate set to OnPriceChange/OnEachTick and OnBarClose
                              Example print:
                              Code:
                              Print(String.Format("CurrentBar index: {0} Time[0]: {1} Open[0]: {2}, High[0]: {3} Low[0]: {4}, Close[0]: {5} State: {6} Calculate: {7}", CurrentBar, Time[0], Open[0], High[0], Low[0], Close[0], State, Calculate));
                              You will see that with Calculate set to OnBarClose, OnBarUpdate is processed once on the close of a bar, and the BarsAgo 0 values represent the bar that has just closed which should not be confused with the developing bar.

                              If Calculate is set to OnPriceChange or OnEachTick, you can note that historical processing still follows updates similar to OnBarClose, but realtime updates will have OnBarUpdate process for the developing bar until it closes. This is because there is no intrabar movement with historical processing. Tick Replay can be used for historical OnEachTick/OnPriceChange, but this is a topic I would recommend opening a new thread on.

                              NinjaTrader uses the first tick of a new bar to signal when a bar has closed. If using Calculate.OnEachTick/OnPriceChange, you can check for the first tick of a new bar and make a BarsAgo reference of 1 to check the bar that has just closed. See the snippet in the documentation page below for an example.

                              IsFirstTickOfBar - https://ninjatrader.com/support/help...ttickofbar.htm

                              As for understanding how if/else statements evaluate, we recommend using prints outside of the condition that show what the values in the condition are, so you may see why it evaluates to true/false and why the code would take the if or else branch.
                              Hi Jim,

                              Thanks for the above answer and latest one also. I'll keep on topic.

                              I've done the Prints Test.

                              The Full Code Updated (with .OnEachTick and IsFirstTickOfBar and the new Prints Code)


                              A Video of my steps:

                              (You can select 1080 HD or download the video)

                              EDIT1 (& EDIT2 at Post's End):

                              at 6:00 Data Box
                              Panel 1 = 66.45 (Open) ✔️ 21/07/21
                              Panel 2 = 66.45 (Open) ✔️ 21/07/21

                              at 17:18 Data Box
                              Panel 1 = 66.45 (Open) ✔️ 21/07/21
                              The Test Results in a Table:
                              Click image for larger version  Name:	vmplayer_oB4D2MhuoK.png Views:	0 Size:	437.3 KB ID:	1164522

                              What do the Prints tell?

                              I'm not sure how to interpret what they are saying.

                              My use is for the Market Analyzer.
                              Click image for larger version  Name:	vmplayer_YQ4ENPrSBm.png Views:	0 Size:	425.9 KB ID:	1164523

                              IF() STATEMENT ALONE TEST

                              Upon Reloading the Market Analyzer:

                              OHLC[0], If Statement Only:
                              Prints = 1 ( 1 day back)
                              MA = 1 ( 1 day back)
                              Upon Reloading the Market Analyzer:

                              OHLC[1], If Statement Only:
                              Prints = 1 ( 1 day back)
                              MA = 2 ( 2 days back)

                              IF() AND ELSE STATEMENT ONLY TEST

                              Upon Reloading the Market Analyzer:

                              OHLC[0], If Statement Only:
                              Prints = 1 ( 1 day back)
                              MA = 1 ( 1 day back)

                              Upon Reloading the Market Analyzer:

                              OHLC[1], If Statement Only:
                              Prints = 1 ( 1 day back)
                              MA = 2 ( 2 days back)

                              Both If() statement alone and IF() Else() statement together return the same results for the Prints as for the Market Analyzer (MA).

                              Please see my video to check my debugging process.
                              Did you mean debugging in another way? If so, please can you tell me the steps?

                              Thanks.

                              I'm not sure what to reason about the Bars Check:

                              Would that do in the current context?

                              if (BarsInProgress != 0)
                              return;

                              if (CurrentBars[0] < 1)
                              return;


                              EDIT 2:

                              Results Table Corrections:

                              Click image for larger version  Name:	vmplayer_kRcGXp5hI3.png Views:	0 Size:	346.6 KB ID:	1164539

                              Table:
                              Attached Files
                              Last edited by Cormick; 07-21-2021, 11:16 AM.

                              Comment


                                #30
                                Hello Cormick,

                                I have recorded a video demonstration showing how you would set this up for daily bars and explaining the need for the CurrentBar check.



                                We look forward to assisting.
                                JimNinjaTrader Customer Service

                                Comment

                                Latest Posts

                                Collapse

                                Topics Statistics Last Post
                                Started by rhyminkevin, Today, 04:58 PM
                                1 response
                                43 views
                                0 likes
                                Last Post Anfedport  
                                Started by iceman2018, Today, 05:07 PM
                                0 responses
                                5 views
                                0 likes
                                Last Post iceman2018  
                                Started by lightsun47, Today, 03:51 PM
                                0 responses
                                7 views
                                0 likes
                                Last Post lightsun47  
                                Started by 00nevest, Today, 02:27 PM
                                1 response
                                14 views
                                0 likes
                                Last Post 00nevest  
                                Started by futtrader, 04-21-2024, 01:50 AM
                                4 responses
                                49 views
                                0 likes
                                Last Post futtrader  
                                Working...
                                X