Announcement

Collapse
No announcement yet.

Partner 728x90

Collapse

Swing comparison not working?

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

    Swing comparison not working?

    Hopefully a simple question - I've already read through threads back to 2017 on this.

    So I made a simple strategy with the following INTENT (which isn't working for some reason): If the Swing indicator has a current low higher than last low, buy when price crosses above current SwingHigh.

    Here is the relevant code:

    // Set 1
    if ((Position.MarketPosition == MarketPosition.Flat)
    && (BarsSinceExitExecution(0, "", 0) != 0)
    && (Swing(2).SwingLowBar(0, 1, 50) >= Swing(2).SwingLowBar(0, 2, 50))
    && (CrossAbove(Close, Swing1.SwingHigh, 1)))
    {
    EnterLong(1, @"LongEntry");
    }

    // Set 2
    if ((Position.MarketPosition == MarketPosition.Flat)
    && (BarsSinceExitExecution(0, "", 0) != 0)
    && (Swing(2).SwingHighBar(0, 1, 50) <= Swing(2).SwingHighBar(0, 2, 50))
    && (CrossBelow(Close, Swing1.SwingLow, 1)))
    {
    EnterShort(1, @"ShortEntry");
    }​

    It doesn't seem to be working, it just shorted under a current high > than previous high AND current low > previous low and no SwingLow was present for it to cross. Any ideas?

    In the picture, it shorted at 19111.50 at 11:23:19 AM on the red falling hammer bar that passed below the green bar over the crosshairs (i.e. second red bar right of the last green bar).

    #2
    Oh, and the strategy is vice-versa: if current high less than previous high, short when we cross below last SwingLow.

    All Swings are strength = 2 (basically searching for Willams' Fractals).

    Comment


      #3
      Hello Mistoffelees,

      Are you adding debugging prints to understand why the condition is not evaluating as true?

      If so, please save the output from the output window to a text file (right-click > Save as) and attach this to your next post.

      If you have not added debugging prints, and if the expected trade(s) are not appearing, this would indicate that the condition to place the order is not evaluating as true and the order is not being submitted, or the order is being ignored for other reasons, or the order is being cancelled or rejected.

      To understand why the script is behaving as it is, such as placing orders or not placing orders or drawing objects when expected, it is necessary to add prints to the script that print the values used for the logic of the script to understand how the script is evaluating.

      In the strategy add prints (outside of any conditions) that print the date time of the bar and all values compared in every condition that places an order.
      The prints should include the time of the bar and should print all values from all variables and all hard coded values in all conditions that must evaluate as true for this action to be triggered. It is very important to include a text label for each value and for each comparison operator in the print to understand what is being compared in the condition sets.

      Prints will appear in the NinjaScript Output window (New > NinjaScript Output window).

      Further, enable TraceOrders which will let us know if any orders are being ignored and not being submitted when the condition to place the orders is evaluating as true.

      I am happy to assist you with analyzing the output from the output window.

      Run or backtest the script and when the output from the output window appears save this by right-clicking the output window and selecting Save As... -> give the output file a name and save -> then attach the output text file to your reply.

      Below is a link to a support article that demonstrates using informative prints to understand behavior and includes a link to a video recorded using the Strategy Builder to add prints.


      Please let me know if I may further assist with analyzing the output or if you need any assistance creating a print or enabling TraceOrders.​
      Chelsea B.NinjaTrader Customer Service

      Comment


        #4
        Hi Chelsea,

        So, first of all could you please confirm whether what I coded was correct?

        (Swing(2).SwingLowBar(0, 1, 50) >= Swing(2).SwingLowBar(0, 2, 50))

        Is that testing correctly for our current low to be greater than or equal to the last "SwingLow" level before it?

        That is literally the entire logic of the little test bot I've made. I do not have coding experience with C#, so before I go off placing debug code everywhere I think I ought to make sure I am at least talking to the program correctly!

        Afterwards I will see if something squirrelly is going on with the cross() coding.

        Comment


          #5
          Hello Mistoffelees,

          Swing low provides a barAgo value for how many bars ago the swing low bar was.
          This would be comparing the number of bars ago of the most recent swing to the number of bars ago of the swing previous, which should always be greater.

          If you want the low price of bar of a swing use the barsAgo from SwingLowBar as the barsAgo index for the Low series.
          Code:
          Low[Swing(2).SwingLowBar(0, 1, 50)]
          Swing(int strength).SwingLowBar(int barsAgo, int instance, int lookBackPeriod)

          I highly recommend that you print these values so that you understand if the values are the expected values or not for the needs of your logic.


          I am also providing a link to a support article with helpful resources on getting started with C# and NinjaScript.
          Chelsea B.NinjaTrader Customer Service

          Comment


            #6
            That's my issue, then. I did put in some debug code and was running it, and I am getting values like 6 and 12 for Swing(2).SwingLowBar(0, 1, 50)​.

            What exactly would be the command to get the price level for the last two Swing Highs and Swing Lows? That is what I need.

            Is Low[Swing(2).SwingLowBar(0, 1, 50)] the correct command? I think you missed an "L" there, but I am only guessing. I can see you help MANY people daily, and I appreciate your help to me, too!

            Comment


              #7
              Hello Mistoffelees,

              Yes, Low[Swing(2).SwingLowBar(0, 1, 50)] would be correct.
              Chelsea B.NinjaTrader Customer Service

              Comment


                #8
                Alright, this is really annoying. The code is loaded and compiled, but it will not let me enable the strategy. No warnings, no explanations, no reasons given at all.

                I copied the code, erased the strategy from the Strategy Editor, created a new one, unlocked the code, pasted, and still the same error. It WAS working, then suddenly not, and I do not know why or how to find out.

                I even went back, created the whole strategy in the Wizard except for two placeholder comparisons Low[0] >= Low[0] and High[0] <= High[0], completed the Wizard strategy, and THEN created a new strategy from that strategy with a new name, unlocked it, and put in the 4 lines of code needed for the strategy to work.

                And this new unlocked strategy WILL NOT ENABLE.

                Also, every time I load NinjaTrader new there is an old strategy in the Strategies tab from the main landing page. Unrelated to this strategy.

                I also got an error about the chart and rendering. If I get that again, I will take a screenshot.

                So, any ideas??? This is REALLY annoying!

                Comment


                  #9
                  Hello Mistoffelees,

                  To confirm, there are no errors appearing on the Log tab of the Control Center when enabling a new instance of the strategy?

                  Please provide an export of the script that I may test on my end and confirm no error are appearing on the Log tab of Control Center for a new instance.

                  To export a NinjaTrader 8 NinjaScript so this can be shared and imported by the recipient do the following:
                  1. Click Tools -> Export -> NinjaScript Add-on...
                  2. Click the 'add' link -> check the box(es) for the script(s) and reference(s) you want to include
                  3. Click the 'Export' button
                  4. Enter the script name in the value for 'File name:'
                  5. Choose a save location -> click Save
                  6. Click OK to clear the export location message
                  By default your exported file will be in the following location:
                  • (My) Documents/NinjaTrader 8/bin/Custom/ExportNinjaScript/<export_file_name.zip>
                  Below is a link to the help guide on Exporting NinjaScripts.


                  Once exported, please attach the file as an attachment to your reply.​
                  Chelsea B.NinjaTrader Customer Service

                  Comment


                    #10
                    After searching, I did find the Log tab. Kind of confusing how there are multiple output panels, but anyway, there WAS an error message:
                    6/11/2024 7:54:57 AM Default Strategy 'AndySwingUnlocked': Error on calling 'OnBarUpdate' method on bar 1: 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.

                    This is strange. I have remade the strategy to use OnEachTick() and that didn't fix anything at all. And I'm doing this in a demo account for testing with active data subscription and dozens if not hundreds of bars loaded (24 range chart, multiple days).

                    I had originally used OnPriceUpdate() to save on recalculating in the strategy, so... anyway. I have exported the strategy and attached it. This is like the 9th attempt or so.
                    Attached Files

                    Comment


                      #11
                      Hello Mistoffelees,

                      Compile errors appear in the NinjaScript Editor. These are caused by incorrect syntax or declarations. If the script is not compiled into the NinjaTrader.Custom.dll assembly, the changes will not be saved.

                      A run-time error is a logical error and appears on the Log tab of the Control Center when a script is run. These are caused by logic mistakes like indexes greater than the size of the collection, using variables with null values, etc.

                      With the error:
                      "Error on calling 'OnBarUpdate' method on bar 1: 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."
                      This is a run time error stating an index was used that was larger than the size of the collection. For example if CurrentBar is 0 and you use Close[1] this will result in an error as there is no bar 1 bar ago when the first bar is being processed.

                      Below is a link to a forum post that discusses how to correct these.


                      What is the specific line of code causing the error?
                      Chelsea B.NinjaTrader Customer Service

                      Comment


                        #12
                        I do not understand. The error is incorrect, there are HUNDREDS of bars on the chart.

                        Where in the code is the error? Your links do not make sense to me, though I am trying to understand. The error they received isn't the same as mine.

                        Comment


                          #13
                          Hello Mistoffelees,

                          You may have a misunderstanding of how Price Series<double> data is processed.



                          Each bar is processed one at a time, starting with the first bar of historical data.
                          The processing doesn't start with the last historical bar or first real-time bar and skip all historical bars, it starts with the first historical bar which is CurrentBar 0.

                          If there are 1,000,000 bars on the chart, the script will start by processing bar 0 in OnBarUpdate(), then bar 1, then bar 2, until it gets to bar 1,000,000.


                          If you are uncertain which line of code is causing the error, add debugging prints above each line that uses an index or barsAgo value. Print the line number in the print and this will make it easy to identify which line was the last print to appear.

                          Below is a link to a support article on adding debugging prints to understand behavior.



                          Where you have stated:
                          "The error they received isn't the same as mine."

                          The error you have received is 'You are accessing an index with a value that is invalid since it is out-of-range.'
                          This is an invalid index error.

                          The error the user has received is 'Index was outside the bounds of the array'.
                          This is also an invalid index error.

                          The issue for both errors, is that an invalid index was used. It will be necessary to identify the index used that was invalid, and then ensure this index cannot be used if it is larger than the size of the collection. For barsAgo indexes, the index must be less than the value of CurrentBar.


                          Chelsea B.NinjaTrader Customer Service

                          Comment


                            #14
                            Okay, apparently the problem is the code you suggested earlier. Setting everything back to what I got from the Wizard gives a strategy that will activate, but the instant I try to even print High[Swing(2).SwingHighBar(0, 1, 50)] or Low[Swing(2).SwingLowBar(0, 2, 50)] or anything like this, it immediately fails and throws the OnBarUpdate() error.

                            The strategy simply hasn't loaded enough data, and never will turn on long enough to GET enough data. At least I think that is the issue, but whatever is going on is the command.

                            Would telling the strategy to load data for the past 50 bars and THEN start doing it's thinking fix it?

                            I am honestly not sure how it was even functioning yesterday. Maybe it doesn't like range charts, I should try it on the time charts.
                            Last edited by Mistoffelees; 06-11-2024, 08:33 AM.

                            Comment


                              #15
                              Hello Mistoffelees,

                              May I confirm that you are requiring CurrentBar to be greater than the barsAgo value produced before attempting to use that as a barsAgo index for the Low series?

                              (It's always necessary to check that an index is less than size of any collection before attempting to use that index in C#)

                              Print(string.Format("{0} | CurrentBar: {1} > Swing(2).SwingLowBar(0, 2, 50): {0}", Time[0], CurrentBar, Swing(2).SwingLowBar(0, 2, 50) ));

                              if (CurrentBar > Swing(2).SwingLowBar(0, 2, 50) && Swing(2).SwingLowBar(0, 2, 50) >= 0)
                              {
                              Print(string.Format("{0} | Condition true | Swing(2).SwingLowBar(0, 2, 50): {1}, Low[{1}]: {2}", Time[0], Swing(2).SwingLowBar(0, 2, 50), Low[Swing(2).SwingLowBar(0, 2, 50)]));
                              }


                              Where you have asked:
                              "Would telling the strategy to load data for the past 50 bars and THEN start doing it's thinking fix it?"

                              I don't have enough information to answer this question. It depends if Swing(2).SwingLowBar(0, 2, 50) is returning a value of greater than 50. If it does then no, this would not fix the issue.
                              If CurrentBar is 50 and ​SwingLowBar() returns a value of 75, then this error will occur because there is no bar 75 bars ago when bar number 50 is being processed.

                              Print the value of SwingLowBar() and CurrentBar and this will tell you what the barsAgo index is, and if this is less than CurrentBar.

                              Use prints to understand behavior, and this can help prevent you from getting stuck.
                              Chelsea B.NinjaTrader Customer Service

                              Comment

                              Latest Posts

                              Collapse

                              Topics Statistics Last Post
                              Started by NullPointStrategies, Yesterday, 05:17 AM
                              0 responses
                              81 views
                              0 likes
                              Last Post NullPointStrategies  
                              Started by argusthome, 03-08-2026, 10:06 AM
                              0 responses
                              150 views
                              0 likes
                              Last Post argusthome  
                              Started by NabilKhattabi, 03-06-2026, 11:18 AM
                              0 responses
                              79 views
                              0 likes
                              Last Post NabilKhattabi  
                              Started by Deep42, 03-06-2026, 12:28 AM
                              0 responses
                              52 views
                              0 likes
                              Last Post Deep42
                              by Deep42
                               
                              Started by TheRealMorford, 03-05-2026, 06:15 PM
                              0 responses
                              59 views
                              0 likes
                              Last Post TheRealMorford  
                              Working...
                              X