Announcement

Collapse
No announcement yet.

Partner 728x90

Collapse

DataLoaded State and Strategy Analyzer

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

    DataLoaded State and Strategy Analyzer

    I have a strategy that I've had lots of issues with in doing backtests on. I could run a backtest on say 100 symbols, write down the results such as trades and percent profitable, then run the strategy again and get different results when zero changes occurred. Also it would often list that say stock X made 4 trades over the test but when I clicked on stock X and choose Trades summary it would show zero to four trades made.

    After way too much troubleshooting and removing sections of code for testing I found that the else if (State == State.DataLoaded) section is sometimes running multiple times. In this section I have a calculation that takes a user defined property of trendDays which is say 1 and multiplies it by 26. Basically if the 1 day trend is positive then buy. It multiplies by 26 as the strategy is run on 15 minute bars and 26 bars is one day so after dataloaded trendDays changes from 1 to 26 where in OnBarUpdate trendDays is the int value for some SMAs.

    Code:
    if (State == State.SetDefaults)
    {
       trendDays = 1;
    }
    else if (State == State.DataLoaded)
    {
       trendDays = trendDays *26;
    }
    protected override void OnBarUpdate()
    {
       if (SMA(Close, trendDays)[0] > SMA(Close, trendDays)[1])
       EnterLong();
    By using Print statements in the DataLoaded section I was able to identify that the dataloaded calc worked as should BUT if I clicked on an individual backtest symbol to view it's results it appears that the DataLoaded section gets run again before displaying the results in the summary window. I can see this by noting the Output window Print(trendDays); would give 26 repeatedly but then after selecting a different stock to view the summary of this value may change to 676 which is 26 * 26 so for sure the dataloaded section ran again and took the now 26 and processed the calc again.

    I've resolved the issue by removing the calc entirely and directly using the number of bars for the trendDays variable instead but this isn't ideal. I can put this code somewhere else if need be but I'm not sure where. It only needs to run once and according to the NT Guide in OnStateChange the dataloaded section is only suppose to run once. IsInstantiatedOnEachOptimizationIteration is set to true.

    Any suggestions?

    Attached Files

    #2
    Hello antrux,

    It is expected that State.SetDefaults would occur more than once. State.DataLoaded is the proper place to set initial values for a script.

    Below is a public link to the LifeCycle of a NinjaScript.


    And a public link to the help guide on OnStateChange().



    What are you trying to acheive by setting this value in State.SetDefaults? Are you trying to change a value of this variable each time the defaults are pushed to the UI? ( when Strategy window is opened, or the list of strategies is generated, or the add button is clicked, or the OK button is clicked, or when the strategy is enabled?)
    Is this to track the number of instances?
    What is the arithmetic for?
    Chelsea B.NinjaTrader Customer Service

    Comment


      #3
      I believe you may have misread the first post. First trendDays is just to be able to enter a user defined variable of whole days and internally it's converted to how many bars that is equal too. I've put all of my user define variables in SetDefaults as that is where the Wizard puts them but that is not the issue.

      It's NOT SetDefaults that i'm seeing an issue with BUT it's DataLoaded that seems to run twice during certain backtesting situations.

      To reproduce:
      Compile strategy code below.
      Open NinjaScript Output Window.
      Open Strategy Analyzer, Type = Standard, Fast Trend = 1, Slow Trend = 3, Instrument = Dow 30, Last, Minute, 15, choose date range, and Run.
      (must be multiple instruments or the issue doesn't appear)
      After the analyzer is complete, choose Trades from the Display dropdown menu.

      A) Note the output window values (with defaults of 1 and 3 fastBars should always be 26 and slowBars 78)
      B) Note the column quantity of "Total # of trades"
      C) Note the Trades listed when viewing the Trades Summary window

      Code:
      #region Using declarations
      using System;
      using System.Collections.Generic;
      using System.ComponentModel;
      using System.ComponentModel.DataAnnotations;
      using System.Linq;
      using System.Text;
      using System.Threading.Tasks;
      using System.Windows;
      using System.Windows.Input;
      using System.Windows.Media;
      using System.Xml.Serialization;
      using NinjaTrader.Cbi;
      using NinjaTrader.Gui;
      using NinjaTrader.Gui.Chart;
      using NinjaTrader.Gui.SuperDom;
      using NinjaTrader.Data;
      using NinjaTrader.NinjaScript;
      using NinjaTrader.Core.FloatingPoint;
      using NinjaTrader.NinjaScript.Indicators;
      using NinjaTrader.NinjaScript.DrawingTools;
      #endregion
      
      //This namespace holds strategies in this folder and is required. Do not change it.
      namespace NinjaTrader.NinjaScript.Strategies
      {
          public class DataLoadedTwice : Strategy
          {
              private SMA smaFast;
              private SMA smaSlow;
      
              private int temp = 0;
      
              protected override void OnStateChange()
              {
                  if (State == State.SetDefaults)
                  {
                      Description    = NinjaTrader.Custom.Resource.NinjaScriptStrategyDescriptionSampleMACrossOver;
                      Name        = "DataLoadedTwice";
                      fastBars        = 1;
                      slowBars        = 3;
                      BarsRequiredToTrade = 0;
                      // This strategy has been designed to take advantage of performance gains in Strategy Analyzer optimizations
                      // See the Help Guide for additional information
                      IsInstantiatedOnEachOptimizationIteration = false;
                  }
                  else if (State == State.DataLoaded)
                  {
                      // Will run on 15 minute bars so convert user defined Days to bars //
                      fastBars = fastBars * 26; // 26 x 15 minute bars is 1 day
                      slowBars = slowBars * 26; // 26 x 15 minute bars is 1 day
      
                      smaFast = SMA(fastBars);
                      smaSlow = SMA(slowBars);
      
                      smaFast.Plots[0].Brush = Brushes.Goldenrod;
                      smaSlow.Plots[0].Brush = Brushes.SeaGreen;
      
                      AddChartIndicator(smaFast);
                      AddChartIndicator(smaSlow);
      
                      // Print to Output window each time Stat.DataLoaded gets processed.
                      temp = temp + 1;
                      Print("########## " + Instrument.MasterInstrument.Name + " ##########");
                      Print("DataLoaded has run " + temp + " time(s).");
                      Print("fastBars should be 26 and is " + fastBars); // 1 x 26 = 26
                      Print("slowBars should be 78 and is " + slowBars); // 3 x 26 = 78
      
                  }
              }
      
              protected override void OnBarUpdate()
              {
                  if (CurrentBar < slowBars)
                      return;
      
                  if (CrossAbove(smaFast, smaSlow, 1))
                      EnterLong();
                  else if (CrossBelow(smaFast, smaSlow, 1))
                      EnterShort();
              }
      
              #region Properties
              [NinjaScriptProperty]
              [Display(ResourceType = typeof(Custom.Resource), Name="Fast Trend in Days", Description="Default is 1", Order=0, GroupName="NinjaScriptStrategyParameters")]
              public int fastBars
              { get; set; }
              [NinjaScriptProperty]
              [Display(ResourceType = typeof(Custom.Resource), Name="Slow Trend in Days", Description="Default is 3", Order=1, GroupName="NinjaScriptStrategyParameters")]
              public int slowBars
              { get; set; }
              #endregion
          }
      }

      Comment


        #4
        In noticing that the 'int temp' did not change I've realized that I can get around this by changing some things up.

        This example no longer has the issue.


        Code:
        #region Using declarations
        using System;
        using System.Collections.Generic;
        using System.ComponentModel;
        using System.ComponentModel.DataAnnotations;
        using System.Linq;
        using System.Text;
        using System.Threading.Tasks;
        using System.Windows;
        using System.Windows.Input;
        using System.Windows.Media;
        using System.Xml.Serialization;
        using NinjaTrader.Cbi;
        using NinjaTrader.Gui;
        using NinjaTrader.Gui.Chart;
        using NinjaTrader.Gui.SuperDom;
        using NinjaTrader.Data;
        using NinjaTrader.NinjaScript;
        using NinjaTrader.Core.FloatingPoint;
        using NinjaTrader.NinjaScript.Indicators;
        using NinjaTrader.NinjaScript.DrawingTools;
        #endregion
        
        //This namespace holds strategies in this folder and is required. Do not change it.
        namespace NinjaTrader.NinjaScript.Strategies
        {
            public class DataLoadedTwice : Strategy
            {
                private SMA smaFast;
                private SMA smaSlow;
        
                private int temp = 0;
                private int fastBars;
                private int slowBars;
        
                protected override void OnStateChange()
                {
                    if (State == State.SetDefaults)
                    {
                        Description    = NinjaTrader.Custom.Resource.NinjaScriptStrategyDescriptionSampleMACrossOver;
                        Name        = "DataLoadedTwice";
                        fBars        = 1;
                        sBars        = 3;
                        BarsRequiredToTrade = 0;
                        // This strategy has been designed to take advantage of performance gains in Strategy Analyzer optimizations
                        // See the Help Guide for additional information
                        IsInstantiatedOnEachOptimizationIteration = false;
                    }
                    else if (State == State.DataLoaded)
                    {
                        // Will run on 15 minute bars so convert user defined Days to bars //
                        fastBars = fBars * 26; // 26 x 15 minute bars is 1 day
                        slowBars = sBars * 26; // 26 x 15 minute bars is 1 day
        
                        smaFast = SMA(fastBars);
                        smaSlow = SMA(slowBars);
        
                        smaFast.Plots[0].Brush = Brushes.Goldenrod;
                        smaSlow.Plots[0].Brush = Brushes.SeaGreen;
        
                        AddChartIndicator(smaFast);
                        AddChartIndicator(smaSlow);
        
                        // Print to Output window each time Stat.DataLoaded gets processed.
                        temp = temp + 1;
                        Print("########## " + Instrument.MasterInstrument.Name + " ##########");
                        Print("DataLoaded has run " + temp + " time(s).");
                        Print("fastBars should be 26 and is " + fastBars); // 1 x 26 = 26
                        Print("slowBars should be 78 and is " + slowBars); // 3 x 26 = 78
        
                    }
                }
        
                protected override void OnBarUpdate()
                {
                    if (CurrentBar < slowBars)
                        return;
        
                    if (CrossAbove(smaFast, smaSlow, 1))
                        EnterLong();
                    else if (CrossBelow(smaFast, smaSlow, 1))
                        EnterShort();
                }
        
                #region Properties
                [NinjaScriptProperty]
                [Display(ResourceType = typeof(Custom.Resource), Name="Fast Trend in Days", Description="Default is 1", Order=0, GroupName="NinjaScriptStrategyParameters")]
                public int fBars
                { get; set; }
                [NinjaScriptProperty]
                [Display(ResourceType = typeof(Custom.Resource), Name="Slow Trend in Days", Description="Default is 3", Order=1, GroupName="NinjaScriptStrategyParameters")]
                public int sBars
                { get; set; }
                #endregion
            }
        }

        Comment


          #5
          Hello antrux,

          Your post #3 doesn't use the same code as your first post.

          if (State == State.SetDefaults)
          {
          trendDays = 1;
          }
          else if (State == State.DataLoaded)
          {
          trendDays = trendDays *26;
          }

          Are you still attempting to set a variable in both State.SetDefaults and State.DataLoaded?

          I can assure you that State.DataLoaded will only run once per iteration.


          The only difference I see in the code between your Post #4 and Post #3 is that you are using separate variables. This would make a difference if
          IsInstantiatedOnEachOptimizationIteration is set to false and the variables are not being reset to initial values in State.DataLoaded. (When IsInstantiatedOnEachOptimizationIteration is false, values are not reset for each new iteration and can accumulate)

          With IsInstantiatedOnEachOptimizationIteration as true, the values would be reset automatically on each new iteration.

          As you have mentioned that IsInstantiatedOnEachOptimizationIteration is true and you are not using this, I would not expect this to make any difference.

          Below is a public link to the help guide on IsInstantiatedOnEachOptimizationIteration.

          Chelsea B.NinjaTrader Customer Service

          Comment

          Latest Posts

          Collapse

          Topics Statistics Last Post
          Started by Jonafare, 12-06-2012, 03:48 PM
          5 responses
          3,984 views
          0 likes
          Last Post rene69851  
          Started by Fitspressorest, Today, 01:38 PM
          0 responses
          2 views
          0 likes
          Last Post Fitspressorest  
          Started by Jonker, Today, 01:19 PM
          0 responses
          2 views
          0 likes
          Last Post Jonker
          by Jonker
           
          Started by futtrader, Today, 01:16 PM
          0 responses
          6 views
          0 likes
          Last Post futtrader  
          Started by Segwin, 05-07-2018, 02:15 PM
          14 responses
          1,791 views
          0 likes
          Last Post aligator  
          Working...
          X