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

Swing Indicator produces index-error only in a special environment

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

    Swing Indicator produces index-error only in a special environment

    I use the Swing-indicator inside another indicator (lets call that one "ChartReader") and hat works fine. But when I use "ChartReader" inside other indicator (lets call it "Tradesignal") or inside a strategy, the index-error occurs:
    "Error on calling 'OnBarUpdate' method on bar 796: You are accessing an index with a value that is invalid since it is out-of-range."

    Bar 796 seems to be connected to the "Strenght" set by my application, which is 797, both in the "ChartReader" for use in the chart and in the strategy or the indicator "Tradesignal" as well, which both run "Swing" with exactly the same parameters. (I followed this lead, results are described later.)

    I tried this solutions without success:
    • MaximumBarsLookBack = MaximumBarsLookBack.Infinite;
    • Saving the whole Swing-Indicator as a new file (other indicator-name, all public variables renamed in the new Swing-indicator and all calling procedures)
    • Setting all variables in this new Swing-indicator to "private", except "Strength" and, of course, the functions "SwingHighBar" and "SwingLowBar" - they are renamed but still public.
    • In the functions "SwingLowBar" and "SwingHighBar"the following lines
    if (instance < 1)
    throw new Exception(string.Format(NinjaTrader.Custom.Resourc e.SwingSwingLowBarInstanceGreaterEqual, GetType().Name, instance));
    if (barsAgo < 0)
    throw new Exception(string.Format(NinjaTrader.Custom.Resourc e.SwingSwingLowBarBarsAgoGreaterEqual, GetType().Name, barsAgo));
    if (barsAgo >= Count)
    throw new Exception(string.Format(NinjaTrader.Custom.Resourc e.SwingSwingLowBarBarsAgoOutOfRange, GetType().Name, (Count - 1), barsAgo));
    were changed to
    if (instance < 1)
    return -1;
    if (barsAgo < 0)
    return -1;
    if (barsAgo >= Count)
    return -1;

    None of this changed neither the correct behaviour of the "Swing"-indicator in the Chart nor the error-message, when called through a strategy or another indicator like "Tradesignal".

    This changes had effects:
    • Adding in the functions "SwingLowBar" and "SwingHighBar" these lines in the beginning:
    if (CurrentBar < Strength)
    return -1;
    [The effect was, that every (!) call of the function was returned with -1 regardless of the CurrentBar the procedure was called at (a single-time frame instrument is used).]
    • Adding this in the beginning of OnBarUpdate()

    if (CurrentBar < 796)
    return;
    [This just moved the problem one bar further. Any other number did the same, even "if (CurrentBar < 20000)", so the problem occurs not only in one of the first bars but always.]

    I understand that the Swing indicator is not supposed to be used for generating trading-signals, but I do need its output in a lookback-procedure that is far enough from "Bar 0", so the results seem to be useful - if it works.

    By the way: The functions "SwingLowBar" and "SwingHighBar" do always return "-1" when called by "Tradsignal" or a strategy (through "Chartreader" which is used in their procedures), but a correct bar-number when called from "Chartreader" directely (always with same parameters, checked by prints in the output-window done by "Chartreader" itself).
    But this may another outcome of he same problem.


    Does anyone know the source of that behaviour of "Swing" and a possible solution?

    Thanks for reading this!







    #2
    Hello jo54321,

    Welcome to the NinjaTrader forums!

    If calling from host script is Update() being called first?


    If calling from a non-data-driven thread like OnRender(), is this called from the call back of TriggerCustomEvent()?


    If the above are good, have you used prints to ensure that the index called is a valid index and greater than the series count?
    Chelsea B.NinjaTrader Customer Service

    Comment


      #3
      Hello Chelsea,

      thank you for your reply!

      Actually Update() is only called in the functions inside the Swing-indicator:

      Code (I changed all variables to "[original name]Inf"):
      #region Functions
      public int SwingLowInfBarInf(int barsAgo, int instance, int lookBackPeriod)
      {
      if (instance < 1)
      return -1;
      if (barsAgo < 0)
      return -1;
      if (barsAgo >= Count)
      return -1;

      Update();

      for (int idx=CurrentBar - barsAgo - StrengthInf; idx >= CurrentBar - barsAgo - StrengthInf - lookBackPeriod; idx--)
      {
      if (idx < 0)
      return -1;
      if (idx >= SwingLowInfSwings.Count)
      continue;

      if (SwingLowInfSwings.GetValueAt(idx).Equals(0.0))
      continue;

      if (instance == 1) // 1-based, < to be save
      return CurrentBar - idx;

      instance--;
      }

      return -1;
      }


      So I have two questions:
      1. The Swing-indicator is called inside the OnBarUpdate()-routine of the host script. Do I have to add "Update()" there additional always before "Swing" is called?

      2. You wrote:
      "If the above are good, have you used prints to ensure that the index called is a valid index and greater than the series count?"
      At first, did you really mean the index has to be greater than the series count? In my understanding it has to be smaller than the series count in order to find a valid value in the series. Did I misunderstand something?
      Second: I did print the values are given to Swing(...).SwingLowBar. They have always been in a valid range. Do you mean another value that represents an index?

      (English is not my native language, so please be patient...)

      Comment


        #4
        Hello jo54321,

        Call the Update() method from the host script, before using the values from the hosted script.

        MyIndicator().Update();


        In C#, any index used any where must be less than the size of the collection.

        Below are links to the help guide.
        https://ninjatrader.com/support/help...nough_bars.htm
        https://ninjatrader.com/support/help...orrect_bar.htm

        And a link to a forum post.
        https://ninjatrader.com/support/foru...13#post1048513

        You have the error:
        "Error on calling 'OnBarUpdate' method on bar 796: You are accessing an index with a value that is invalid since it is out-of-range."

        This means you have used an invalid index.
        What is the specific line of code causing the error?
        What is the index used, what is the size of the collection?
        Chelsea B.NinjaTrader Customer Service

        Comment


          #5
          Hello Chelsea,

          thank you for your support.

          I did find out that the problem does occur inside the OnBarUpdate()-procedure of the host-host script ("TradeSignal") when the host-script ("Chartreader") has to deliver its value for the first time. Then the hosted Swing-indicator runs through its lines and line 140 produces the error. The code of the line is:
          swingHighSwings[Strength] = isSwingHigh ? swingHighCandidateValue : 0.0;
          It is line 140 from the original NinjaTrader-indicator "Script". That means at this point swingHighSwings-series does not have an element at [Strength], but only when called by a host-script, that is called by another host-script itself.
          An "Update()"-command in the host-host-script ("TradeSignal") before the line that requests data from the host-script ("Chartreader") does not solve the problem.



          Here you find the structure of the three programs I believe to be relevant:

          public class TradeSignal : Indicator
          {
          private ChartReader reader1;
          ...
          if (State == State.SetDefaults)
          {
          MaximumBarsLookBack = MaximumBarsLookBack.Infinite;
          ...
          }
          else if (State == State.DataLoaded)
          {
          reader1= ChartReader(Close, false, 5, false, true, true, false, false, false, false);
          ...
          }

          protected override void OnBarUpdate()
          {
          if (CurrentBar < 4000)
          return;
          ...
          if (reader1.Trade[0] > 0)
          {
          // Go Long
          ...
          }

          }
          // By the first time data from reader1 is requested the error occurs (Output: "This is TradeSignal @ bar 4000") - then the error follows.
          // If I add "Update()" here the error occurs every bar from now on, otherwise once, but then the Swing-module always return -1.


          ///////////////////////////

          public class ChartReader : Indicator
          {
          ...
          if (State == State.SetDefaults)
          {

          MaximumBarsLookBack = MaximumBarsLookBack.Infinite;
          ...

          }
          else if (State == State.Configure)
          {
          ChangeDef = 4;
          DistMin = 797;
          EZone = 2917;
          ...
          }
          else if (State == State.DataLoaded)
          {
          if (CalledByTradeSignal)
          PrintTo = PrintTo.OutputTab1;
          else
          PrintTo = PrintTo.OutputTab2;
          }

          protected override void OnBarUpdate()
          {
          if (CurrentBar < 3720)
          return;
          ...
          Print("Calling SwingInf now @ bar "+CurrentBar);
          int lastswing = SwingInf(Low, Convert.ToInt32(Math.Floor(Convert.ToDouble(DistMi n/2)))).SwingLowInfBarInf(1, 1, EZone);
          Print("#"+CurrentBar+" lastswing="+lastswing+" || Low[0]="+Low[0]+" | DistMin/2="+(Math.Floor(DistMin/2))+" | EZone="+EZone);

          // If the routine is called by "Chartreader" OutputWindow2 shows this:

          // Calling SwingInf now @ bar 3773
          // #3773 lastswing=726 || Low[0]=3384,75 | DistMin/2=398 | EZone=2917

          // If the routine is called by "TradeSignal" OutputWindow1 shows this:
          // Calling SwingInf now @ bar 3773
          // Indicator 'SwingInf': Error on calling 'OnBarUpdate' method on bar 796: You are accessing an index...
          // #3773 lastswing=-1 || Low[0]=3384,75 | DistMin/2=398 | EZone=2917
          // At this point the index-error has occurred earlier, so it does not respond here appropriately. Alling "Update()" would only repeat the index-error.
          ...

          ///////////////////////////

          public class SwingInf : Indicator
          {
          ...
          if (State == State.SetDefaults)
          {

          MaximumBarsLookBack = MaximumBarsLookBack.Infinite;
          ...

          }
          The further routines are identically to the original Swing-indicator.


          I would very much appreciate your further advice in this issue.



          Comment


            #6
            Hello jo54321,

            This is Jim responding on behalf of Chelsea who is out of the office at this time.

            In order to provide an accurate response, I would like to test on my end with a simplified script. I have attached very barebones that simply host the Swing indicator called "SwingHost" and another which hosts that indicator called "SwingHostHost."

            Could you make changes to these scripts so they can demonstrate where the indexing fails in the "SwingHostHost" script, but not in the "SwingHost" script?

            Please also let us know how you have set up to hit the errors with these scripts.
            Attached Files
            JimNinjaTrader Customer Service

            Comment


              #7
              Hello Jim,

              thank you very much for your support!
              I tried to transfer the basic logic in the files you sent me, but the error did not occur. In order to find the logic inside my indicator that creates the problem I copied my indicators and renamed them (filename and, of course, replacing the name the file inside with the find-and-replace-function / replace all (32 replacements). Finally this solved the problem! I do not understand how, but everything is fine now. If could give me a hint what this is about, it may help me avoiding problems in the future.

              Comment


                #8
                Hello jo54321,

                If you have confirmed the line causing the error, by commenting this out and the error stopped, and then when uncommenting the line the error comes back, and the error is caused by:
                swingHighSwings[Strength] = isSwingHigh ? swingHighCandidateValue : 0.0;

                This would indicate that swingHighSwings.Count() is less than the value of Strength.

                A check to ensure that Strength is less than CurrentBar (or less than Count() - 1) may correct the invalid index.
                Chelsea B.NinjaTrader Customer Service

                Comment


                  #9
                  Hello Chelsea,

                  I will have that in mind, thank you!

                  Comment

                  Latest Posts

                  Collapse

                  Topics Statistics Last Post
                  Started by LawrenHom, Today, 10:45 PM
                  0 responses
                  1 view
                  0 likes
                  Last Post LawrenHom  
                  Started by love2code2trade, Yesterday, 01:45 PM
                  4 responses
                  28 views
                  0 likes
                  Last Post love2code2trade  
                  Started by funk10101, Today, 09:43 PM
                  0 responses
                  7 views
                  0 likes
                  Last Post funk10101  
                  Started by pkefal, 04-11-2024, 07:39 AM
                  11 responses
                  37 views
                  0 likes
                  Last Post jeronymite  
                  Started by bill2023, Yesterday, 08:51 AM
                  8 responses
                  44 views
                  0 likes
                  Last Post bill2023  
                  Working...
                  X