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

Reverse 3ngineering the Swing Indicator

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

    Reverse 3ngineering the Swing Indicator

    Ninjas!

    As a journeyman programmer and long time Market enthusiast, I'm addicted to NT! I've asked for help gaining a deeper understanding of all things Ninja and many of you have responded. For this I Thank You! I'd like to "shout out" to user: bltdavid for his wonderful dissertations for my / our benefit. If you haven't seen my last two posts, check them out. bltdavid gave a few really great lessons.

    Now...
    I've opened the Swing Indicator and I'm trying to reverse engineer it. It's very interesting. I thought I could grasp it but there's a few "effects" that cause an offset that I can't figure out why... Ultimately, I'm hoping to extend it once I understand the logic / pattern a little better. I was wondering if there's anyone out there that might understand the Swing indicators' logic (code level) in depth and could explain how and why it's written the way it is.

    @ user sl..... - (with kindness and respect) I know I strike you as a nuisance. Please, hold the sarcasm on this, and my future posts. If you have trouble contributing information that is useful and constructive, then please don't post a reply.

    Thank You!

    Rob

    #2
    Originally posted by RobVig View Post
    As a journeyman programmer and long time Market enthusiast, I'm addicted to NT! I've asked for help gaining a deeper understanding of all things Ninja and many of you have responded. For this I Thank You! I'd like to "shout out" to user: bltdavid for his wonderful dissertations for my / our benefit. If you haven't seen my last two posts, check them out. bltdavid gave a few really great lessons.
    Thanks!
    [Edit: He's referring to my "tutorial essays" in threads here and here. ]

    Originally posted by RobVig View Post
    Now...
    I've opened the Swing Indicator and I'm trying to reverse engineer it. It's very interesting. I thought I could grasp it but there's a few "effects" that cause an offset that I can't figure out why... Ultimately, I'm hoping to extend it once I understand the logic / pattern a little better. I was wondering if there's anyone out there that might understand the Swing indicators' logic (code level) in depth and could explain how and why it's written the way it is.
    I understand it very well. Fire away with your questions!

    Hint #1:
    Remember when I said that the mutability of values of indexers n > 0 is a rarely used feature of a DataSeries? Well, I stand by that, but Swing.cs is one of those rare indicators that does reach back and update older slot values.

    Hint #2:
    Make sure you understand that DataSeries 'Set' method has two signatures. One method simply updates the value at slot 0, the other method updates the value stored at the specified slot. Swing.cs uses both signatures of the 'Set' method.

    Hint #3:
    Swing.cs uses ArrayList, and relies upon specific functionality of the RemoveAt method -- make sure you understand the 'queue' nature of what Swing.cs is using the ArrayList data structure to achieve. What I mean is, study how the Add and RemoveAt methods are used together to achieve a "moving window" of values.

    Hint #4:
    Make sure you know exactly what the Strength parameter means. A swing point (if detected) is the middle value in the moving window. If this middle value is the highest of all values on the left, and highest of all values on the right, then a swing high has been detected at this middle value. Same idea for a swing low.

    Make sure you completely understand this "moving window" metaphor. The size of the window is based upon the Strength parameter. That is, the algorithm waits until the moving window contains exactly '(2 * n) + 1' elements. Strength is 'n' and the '+ 1' is the middle value.

    Why? Because you need 'n' values to the left and 'n' values to the right of the candidate swing point to be all higher or all lower to confirm that swing point. Once the ArrayList cache is full, the algorithm confirms the middle value (aka the candidate) is a swing point by checking the 'n' values before and after the middle value.

    This is why a swing point is not known (aka confirmed) until after 'n' bars have passed. This is also why the algorithm needs to reach back into its internal tracking DataSeries and update previous slots after it found a swing point -- it doesn't know it found a confirmed swing point until after 'n' bars have passed.

    Study this swing detection code carefully.

    Hint #5:
    Do you know what CalculateOnBarClose (abbreviated COBC) is yet? The user sets COBC to True or False in the property settings, and the indicator author typically codes their OnBarUpdate to handle either case. The code in OnBarUpdate follows a common model that is designed to accommodate the effects of the COBC setting,

    Code:
    protected override OnBarUpdate()
    {
        if (saveCurrentBar != CurrentBar)
        {
            ... this code runs when bar closes regardless of COBC setting ...
            saveCurrentBar = CurrentBar;
        }
        else
        {
            ... this code runs on every tick but only if COBC is false ...
            ... this code does not run on the first tick, that is handled above ...
        }
    }
    My guess is this 'saveCurrentBar' technique is a legacy code pattern, probably dating back to older versions of NinjaTrader before FirstTickOfBar became the newer recommended way to handle the effects of the COBC setting.

    These hints only scratch the surface. The Swing indicator is indeed very interesting.

    Keep in mind, the Swing indicator is also complicated, and rather clever. But, it is a very good indicator to master if you want to become an expert in NinjaScript.

    Kudos to you, sir, for tackling this beast so soon!
    Last edited by bltdavid; 06-08-2016, 01:51 PM. Reason: added many helpful links

    Comment


      #3
      Hello Rob,

      Thank you for your post.

      bltdavid provides some good insight into the Swing indicator. I notice the biggest hang up to be the strength, as bltdavid mentioned.

      Please let us know if you have any specific questions.
      Last edited by NinjaTrader_PatrickH; 06-10-2016, 07:26 AM.

      Comment


        #4
        Patrick,

        Swoosh! bltdavid to the rescue again or what?!?!

        Sorry for my delayed response... I've been studying btldavids post and trying to compose a response. Difficult using this medium... I'm going to go over it and over it, before I ask any questions to try and keep this thread as distilled as possible.
        Last edited by RobVig; 06-09-2016, 06:31 PM.

        Comment


          #5
          David,

          I've read your post a few times and Swing is starting to make sense... I'm seeing the light. It's brilliant! Questions forthcoming....

          Rob

          PS: This is key...

          Originally posted by bltdavid View Post
          Make sure you completely understand this "moving window" metaphor. The size of the window is based upon the Strength parameter. That is, the algorithm waits until the moving window contains exactly '(2 * n) + 1' elements. Strength is 'n' and the '+ 1' is the middle value.
          Last edited by RobVig; 06-09-2016, 07:32 PM.

          Comment


            #6
            David, here's Question #001

            On line 101 of Swings.cs

            swingHighSwings.Set(strength, isSwingHigh ? swingHighCandidateValue : 0.0);

            Can you walk through this test? What values / combinations of "strength" and "isSwingHigh" would dictate true or false?

            As always, Thank You for sharing your wisdom for the benefit of others!
            Rob
            Last edited by RobVig; 06-10-2016, 09:27 AM.

            Comment


              #7
              Originally posted by RobVig View Post
              David, here's question #001

              On line 101 of Swings.cs

              swingHighSwings.Set(strength, isSwingHigh ? swingHighCandidateValue : 0.0);

              Can you walk through this test? What values / combinations of "strength" and "isSwingHigh" would dictate true or false?
              What you're missing is understanding how isSwingHigh is set to false inside the check loops. There are two check loops, one for the left side of the middle value of the "moving window", and another check loop for the right side. These two check loops are there to confirm the middle candidate value is actually a swing value.

              [Edit: The purpose of the check loops is to decide if the middle value (aka, the swing candidate) is the highest value of all values in the moving window. This is the "ah-hah" moment when Swing knows it has found a confirmed swing high. So, isSwingHigh is just a flag for when a confirmed swing high is found. Note how the check loops set isSwingHigh to false when the candidate is proven not a swing.]

              Line 91: isSwingHigh starts out as true.
              Line 95: check loop sets isSwingHigh to false due to a higher value left of candidate.
              Line 99: check loop sets isSwingHigh to false due to a higher value right of candidate.

              Those check loops don't "break" after setting isSwingHigh to false, but they don't have to. Once isSwingHigh is set to false by either check loop, it will still be false when used by the ternary operator inside the 'Set' method at line 101.

              When isSwingHigh is false, due to swingHighCandidateValue failing the check loops, the code reaches back into the tracking DataSeries and sets slot 'n' to 0.0.

              When isSwingHigh is true, due to swingHighCandidateValue passing the check loops, the code reaches back into the tracking DataSeries and sets slot 'n' to swingHighCandidateValue.

              Strength = 'n', same as before. Thus, the mutability of older values in the DataSeries is essential for Swing.cs to update its internal swing tracking DataSeries.
              Last edited by bltdavid; 06-11-2016, 10:31 AM.

              Comment


                #8
                Originally posted by bltdavid View Post
                Line 95: check loop sets isSwingHigh to false due to a higher value left of candidate.
                Line 99: check loop sets isSwingHigh to false due to a higher value right of candidate.
                Ah!
                for (int i = 0; i < strength; i++) // <<<<< The left side [0-4]
                for (int i = strength + 1; i < lastHighCache.Count; i++) // >>>>> The right side [6-10]

                Originally posted by bltdavid View Post
                Hint #5:
                Do you know what CalculateOnBarClose (abbreviated COBC) is yet? ...
                Yes. I am familiar with this concept.

                - - - -

                Question #002

                On line 89 (or so) " if (lastHighCache.Count == (2 * strength) + 1) " statement begins and ends around line 144. Just prior to the closing of that statement there is a final "if / else" block (line 134) that appears to loop through the "left side". My question is: What purpose does the "swingHighSeries" DataSeries serve?

                Thank You,
                Rob
                Last edited by RobVig; 06-10-2016, 11:22 AM.

                Comment


                  #9
                  Originally posted by RobVig View Post
                  Question #002

                  On line 89 (or so) " if (lastHighCache.Count == (2 * strength) + 1) " statement begins and ends around line 144. Just prior to closing of that statement there is a final "if / else" block (line 134) that appears to loop through the "left side". My question is: What purpose does the "swingHighSeries" DataSeries serve?
                  [Edit: I think your line numbers are off. Lines 134 & 144 don't show what you're describing. I use an editor that expands all regions and always displays absolute line numbers. I mean, I only use NinjaScript editor to compile, I use gvim to edit all my code, so perhaps your line numbers are off due to your particular editor?]

                  The swingHighSeries is the "backing store" for the SwingHigh property.

                  The description of Swing shows two different syntax descriptions,

                  Code:
                  Syntax - Bars Ago
                  Syntax - Value
                  You're basically asking about the second 'Value' syntax. That syntax requires the use of swingHighSeries, because Swing needs an internal DataSeries providing the private storage (aka backing store) for the public SwingHigh property.

                  What's the purpose? Well, each element retrieved by SwingHigh via indexer '[n]' is returning the most recent confirmed swing high value (if one existed) recorded for that bar 'n' bars ago.

                  What I mean is, SwingHigh returns prior swing status information on a per-bar basis. It returns either 0 (no swing active) or the current swing high/low value active at the time of that bar n bars ago.

                  If you wanted to look back 10 bars ago, and ask the question, "Did that bar 10 bars ago have an active swing high already in progress found from a prior bar?" Well, SwingHigh returns an answer for that question. If it returns 0, no swing high was active at the time of that bar, otherwise the answer is yes and you have the swing high value itself.

                  Whether this per-bar status information is useful to you, that depends upon your needs.
                  Last edited by bltdavid; 06-10-2016, 11:22 AM.

                  Comment


                    #10
                    Thank You for replying David!

                    Originally posted by bltdavid View Post
                    I think your line numbers are off. Lines 134 & 144 don't show what you're describing.
                    Sorry for the confusion. I copied and pasted the Swing code into VS and hit the “return” key a few times to separate the code for readability. I’ll make sure it’s accurate next time.

                    Comment


                      #11
                      Originally posted by bltdavid View Post
                      Whether this per-bar status information is useful to you, that depends upon your needs.
                      Btw, If you want to see an example of Swing in action, try studying this indicator,

                      Comment

                      Latest Posts

                      Collapse

                      Topics Statistics Last Post
                      Started by Barry Milan, Yesterday, 10:35 PM
                      5 responses
                      16 views
                      0 likes
                      Last Post NinjaTrader_Manfred  
                      Started by DanielSanMartin, Yesterday, 02:37 PM
                      2 responses
                      13 views
                      0 likes
                      Last Post DanielSanMartin  
                      Started by DJ888, 04-16-2024, 06:09 PM
                      4 responses
                      12 views
                      0 likes
                      Last Post DJ888
                      by DJ888
                       
                      Started by terofs, Today, 04:18 PM
                      0 responses
                      11 views
                      0 likes
                      Last Post terofs
                      by terofs
                       
                      Started by nandhumca, Today, 03:41 PM
                      0 responses
                      8 views
                      0 likes
                      Last Post nandhumca  
                      Working...
                      X