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

Strategy Analyzer with MTF Strategy

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

    Strategy Analyzer with MTF Strategy

    Hello all,

    I would like to be able to use strategy analyzer for backtesting my strategy. Based upon the NT literature that I have read, as well as relevant posts in this forum, it should work for my strategy, but it doesn't.

    Some information about my setup...

    Half of the entries in my strategy are intrabar entries, the other half enter at the end of the entry candle. I run my strategy on OnPriceChange. I use a 15-minute candlestick series, as well as a 1-range series.

    My strategy runs perfectly on a playback connection and the entries at the end of the candle execute accurately in SA, it's the intrabar entries that do not. They instead enter at the start of the bar after the entry conditions were met.

    The check at the top of my strategy logic ensures that everything is run on the primary time frame (CurrentBar != 0 returns the strategy). I have tried specifying as an argument that the intrabar trades execute on the secondary time frame, as is suggested in the literate, however I ended up with the same result in SA. I also tried running SA with increased granularity, but since I already had a secondary series running, it wouldn't allow me to do so.

    Okay, hopefully that is enough information to light a bulb over one of your heads, if you need more, please ask. I would very much appreciate if somebody could walk me through how to set this up as it would greatly increase the speed of each test-optimization loop.

    Thank you!

    #2
    Hello lunardiplomacy,

    Do you have 1 tick intra-bar granularity for accurate order fills and TickReplay enabled for Calculate in historical data?

    Chelsea B.NinjaTrader Customer Service

    Comment


      #3
      Chelsea, thanks for getting back to me,

      Duh, TickReplay, I knew there was something I was forgetting to try.

      So, I followed to instructions to "Show Tick Replay" in options, opened SA, enabled it, and ran my strategy over a few days when I knew there would be trades, and there was nothing. Do I need to add anything to my code in order for this to function properly? Just to clarify, it didn't take any trades at all, whereas before without tick replay it would take trades, it just represented them inaccurately.

      I am still running on OnPriceChange, should i switch to OnBarClose? and do i need to add the method IsFirstTickOfBar? I read something about that in what you just sent me, but didn't fully understand if it was necessary for what I'm looking to do.

      Also, what do you mean by "Do you have 1-tick intrabar granularity"? I have a 1-range secondary series as I mentioned in my original post, but i can change this to 1-tick if it will help. I just thought 1-range would be a little less intense on my computer.

      Thanks, Chelsea
      Last edited by lunardiplomacy; 01-08-2020, 04:18 PM.

      Comment


        #4
        Hello lunardiplomacy,

        If you call EnterLong() outside of any conditions do you still see no trades?

        Does the connection support historical tick data (for TickReplay)?

        Any errors?


        TickReplay enabled the Calculate to be On price change, so you don't have to change that to On bar close.

        Intra-bar granularity is adding a 1 tick series for increasing accuracy in fill prices by submitting orders to that 1 tick series.

        Increasing accuracy means finer granularity, which means more processing is necessary.
        Last edited by NinjaTrader_ChelseaB; 01-08-2020, 04:40 PM.
        Chelsea B.NinjaTrader Customer Service

        Comment


          #5
          So....

          Something happened. All I did was change the length of the backtesting range, and these are the results I ended up with. Trust me, this isn't a HFT machine, this is very unusual, log is reporting nothing out of the ordinary ... any ideas?

          Edit: Trades per direction is set to 1, furthering the nonsense that is this image

          Edit: Can you clarify what you mean by, "does the CONNECTION support historical tick data"? I'm quite certain it does. Ninjatrader Continuum?

          Click image for larger version  Name:	TickReplaynonsense.PNG Views:	0 Size:	207.2 KB ID:	1083212
          Last edited by lunardiplomacy; 01-08-2020, 05:10 PM.

          Comment


            #6
            Hello lunardiplomacy,

            If you are wanting to understand the behavior of strategy, use prints to print all values used in conditions along with the time of the bar.

            Below is a link to a forum post that demonstrates.


            I am happy to assist with analyzing the output from the prints if you would like to provide this.

            Yes, NinjaTrader Continuum does support historical tick data.

            Below is a link to the NinjaTrader 8 help guide on Data by provider which shows the supported connection technologies and the types of data these connections support.
            Chelsea B.NinjaTrader Customer Service

            Comment


              #7
              Hello again, Chelsea. Hope you slept well.

              I am familiar with print statements, and in this case they were somewhat helpful. But, along with that information I did some reading in the forum and NT8 literature last night, and I am pretty certain at this point that the issue comes down to separating the logic for my entries so that they work as intended.

              It seems there are maybe a few ways I could go about this, and the last thing I'll ask of you is just that you guide me in the right direction that I should take for the approach and syntax involved.

              So, if I'm not mistaken, I could run my strategy to calculate on OnBarClose and separate the intra and bar-close entries with a BarsInProgressIndex == 0 for bar-close entries and ==1 for intra entries.

              Or, alternatively, again if I'm not mistaken, I could calculate OnPriceChange and run both entries through the same BarsProgIndex, but enclose the bar-close entries within brackets that specify IsFirstTickOfBar.

              Is there a better way to go about this? I would assume OnBarClose method to be preferable if for no other reason that for the sake of efficiency, but I'm not sure.

              Code:
              if (CurrentBars[0] < 1 || CurrentBars[1] < 1)
              return;
              
              if (BarsInProgress == 0)
              {
              if ((Low[0] <= zzSuicideBands1.Lower[0]) && (Open[0] > zzSuicideBands1.Lower[0]) && (Close[0] > zzSuicideBands1.Lower[0]))
              {
              EnterLong(Convert.ToInt32(DefaultQuantity), @"Y-1Long");
              }
              }
              
              if (BarsInProgress == 1)
              {
              if ((Low[0] <= zzSuicideBands1.Lower[0]) && (Open[0] > zzSuicideBands1.Lower[0]) && (Close[0] > Closes[0][1]))
              {
              EnterLong(Convert.ToInt32(DefaultQuantity), @"Y-1StopLong");
              }
              }
              Would this be the correct syntax? by the way, it's running in OnBarClose calculation. And for the second method I mentioned, would I just return after BiP != 0 and switch it out in the first entry with (IsFirstTickOfBar)? I apologize if this seems nitpicky, I know this is in the literature, I am just asking if there is a better way to do this because I want to make sure it is optimal before I proceed writing the rest of the entries and other logic.

              Thanks, Chelsea

              ** as a note, the indicator name is in reference to a sports drill called suicides that resembles the strategy's operation, I don't condone suicide or self-harm and I don't want to offend anyone.
              Last edited by lunardiplomacy; 01-09-2020, 09:13 AM.

              Comment


                #8
                Hello lunardiplomacy,

                Using Calculate with On price change would result in less cycles of OnBarUpdate and would be more efficient.

                However, in historical this would require TickReplay which adds a 1 tick series in anyway.

                So this would basically be the same as just adding a 1 tick series yourself. (TickReplay was introduced intending to make adding a 1 tick series for triggering actions easier for beginner programmers)

                Either works.

                Because TickReplay doesn't work with High Order Fill Resolution, I would recommend just adding the 1 tick series and using the BarsInProgress to control actions.
                Chelsea B.NinjaTrader Customer Service

                Comment


                  #9
                  Chelsea,

                  That is PRECISELY what I did. I used the code that I provided above, opened SA, turned on TickReplay and ran it.

                  Click image for larger version

Name:	NotIntraEntry.PNG
Views:	284
Size:	3.4 KB
ID:	1083280

                  That first green bar in the image SHOULD enter as it (the 1-tick series) crosses up above the bottom of the previous candle's close (first red bar, intra entry), but instead it enters as if it is waiting for the bar to close. Print statements are not really helping me understand this, unless I'm just printing the wrong information. All I want to see is that little blue arrow point to the intersection of the price that connects those two bars and I will be beyond happy. I just can't seem to make that happen.

                  I know there is nothing wrong with the condition. And, I already have a 1-tick series added in my strategy, which is what the intra entry is based on.

                  Also, wait OnPriceChange would result in LESS cycles? Wouldn't it cycle through every time the price changes rather than once per the creation of a new bar and therefore be less efficient? Or do I misunderstand.

                  Comment


                    #10
                    Hello lunardiplomacy,

                    If you have added a 1 tick series, then TickReplay or changing the Calculate setting is not necessary to trigger intra-bar actions. But you may still need TickReplay for running indicators intra-bar.

                    Prints would tell you if the condition is being checked on every bar or if the condition is not evaluating as true.
                    This would tell you exactly why you are or are not seeing an order on the bar or price you are expecting. Prints are used to understand behavior. You are wanting to understand the behavior.

                    If you do add the prints and provide the output I can assist with analyzing the output and understanding the behavior.

                    Yes, with On price change OnBarUpdate() is only run when the price changes. With On each tick On bar updates on every received tick. There can be many ticks at the same price level resulting in many more runs of OnBarUpdate().
                    Last edited by NinjaTrader_ChelseaB; 01-09-2020, 11:01 AM.
                    Chelsea B.NinjaTrader Customer Service

                    Comment


                      #11
                      Right, I realized afterwards you were talking about a tick series specifically running more efficiently on OnPriceChange because of the true horizontal movement, otherwise OnBarClose is more efficient.

                      I read the previous forum post you sent me on print statements, and it seems they can become much more useful than I previously understood, however also much more involved.

                      Can I please ask you to copy and paste the code I sent you above with the correct print statements added in the correct places? Then, if there is something in the output that I don't understand I can send it your way? I am sorry if I'm asking a lot of you, but I don't want to mess up the prints and then be giving you inaccurate information post hoc. Besides that, it would help me to understand how to use prints most effectively if I could see how they are placed within my own code.

                      Thanks, Chelsea. You're a saint.

                      Comment


                        #12
                        Hello lunardiplomacy,

                        While our support does not typically do the debugging work of writing the prints, I went ahead and did this as it is a learning experience for you.

                        Code:
                        if (CurrentBars[0] < 1 || CurrentBars[1] < 1)
                        return;
                        
                        Print(string.Format("{0} | BarsInProgress: {1}", Time[0], BarsInProgress));
                        
                        if (BarsInProgress == 0)
                        {
                            Print(string.Format("{0} | Low[0]: {1} <= zzSuicideBands1.Lower[0]: {2} && Open[0]: {3} > zzSuicideBands1.Lower[0]: {2} && Close[0]: {4} > zzSuicideBands1.Lower[0]: {2}", Time[0], Low[0], zzSuicideBands1.Lower[0], Open[0], Close[0]));
                        
                            if ((Low[0] <= zzSuicideBands1.Lower[0]) && (Open[0] > zzSuicideBands1.Lower[0]) && (Close[0] > zzSuicideBands1.Lower[0]))
                            {
                                EnterLong(Convert.ToInt32(DefaultQuantity), @"Y-1Long");
                            }
                        }
                        
                        if (BarsInProgress == 1)
                        {
                            Print(string.Format("{0} | Low[0]: {1} <= zzSuicideBands1.Lower[0]: {2} && Open[0]: {3} > zzSuicideBands1.Lower[0]: {2} && Close[0]: {4} > Closes[0][1]: {5}", Time[0], Low[0], zzSuicideBands1.Lower[0], Open[0], Closes[0][1]));
                        
                            if ((Low[0] <= zzSuicideBands1.Lower[0]) && (Open[0] > zzSuicideBands1.Lower[0]) && (Close[0] > Closes[0][1]))
                            {
                                EnterLong(Convert.ToInt32(DefaultQuantity), @"Y-1StopLong");
                            }
                        }
                        Chelsea B.NinjaTrader Customer Service

                        Comment


                          #13
                          I know, Chelsea, and I knew I pushing it a little. But honestly, already this makes a lot more sense to me now. So these "{ }" are creating a list of values which are printed at the end after the comma as if to say "respectively" and if the same value occurs twice it gets the same list number. The only thing I don't understand is the " | " after {0} and why it is only done once. But I'll just be sure to use it in this way in the future regardless.

                          Thank you so much for your help, I'm always glad when you're the dev who responds to my queries, you have been a very big help. I will run this and try not to come back to you with the outputs unless I absolutely positively can't hack it.

                          Thanks again,
                          LD

                          Comment


                            #14
                            Hello LD,

                            The vertical line is just for a label. I think it makes the print look nicer. It is not required.

                            And I'm happy to help with analyzing the output.
                            Chelsea B.NinjaTrader Customer Service

                            Comment

                            Latest Posts

                            Collapse

                            Topics Statistics Last Post
                            Started by Skifree, Today, 03:41 AM
                            1 response
                            2 views
                            0 likes
                            Last Post Skifree
                            by Skifree
                             
                            Started by usazencort, Today, 01:16 AM
                            0 responses
                            1 view
                            0 likes
                            Last Post usazencort  
                            Started by kaywai, 09-01-2023, 08:44 PM
                            5 responses
                            603 views
                            0 likes
                            Last Post NinjaTrader_Jason  
                            Started by xiinteractive, 04-09-2024, 08:08 AM
                            6 responses
                            23 views
                            0 likes
                            Last Post xiinteractive  
                            Started by Pattontje, Yesterday, 02:10 PM
                            2 responses
                            22 views
                            0 likes
                            Last Post Pattontje  
                            Working...
                            X