Announcement

Collapse
No announcement yet.

Partner 728x90

Collapse

Access Strategy Analyzer Time Frame Start/End Date from NinjaScript

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

    Access Strategy Analyzer Time Frame Start/End Date from NinjaScript

    Hello,

    Is it possible to programmatically adjust the start/end date of an optimization being run from the Strategy Analyzer?

    I have extended the base DefaultOptimizer code and can easily reference the OptimizationParameters array so I assumed that the start/end date should be similarly referenceable.

    Thx

    #2
    Hello TheFil,

    I am not aware of any way to change that through code, are you looking to set some kind of a default for the from and to dates?

    In general no tools in the platform are set up to have dynamic data series meaning that all data series are configured manually and then scripts use those series when applied. The same concept works in the analyzer where you configure the series in the UI before running the test.
    JesseNinjaTrader Customer Service

    Comment


      #3
      Thanks NinjaTrader_Jesse,

      I was able to modify the DefaultOptimizer and change the dates by referencing Strategies[0].From and Strategies[0].To, however the output of the optimization only retains the last set of dates passed-in, even though it has iterated across all sets of dates...

      Below is a log output that shows the dates being adjusted programmatically:

      Click image for larger version

Name:	changeDates.png
Views:	169
Size:	239.4 KB
ID:	1203615

      Comment


        #4
        And the modified Optimizer code:

        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.Gui.Tools;
        using NinjaTrader.Data;
        using NinjaTrader.NinjaScript;
        using NinjaTrader.Core.FloatingPoint;
        
        #endregion
        
        //This namespace holds Optimizers in this folder and is required. Do not change it.
        namespace NinjaTrader.NinjaScript.Optimizers
        {
        public class OptCustomOptimizer : Optimizer
        {
        private int[] enumIndexes;
        private int dateIndex;
        private int iterationIndex;
        
        protected override void OnStateChange()
        {
        if (State == State.SetDefaults)
        {
        Description = @"Modified version of DefaultOptimizer for the batching of monthly and weekly optimization runs";
        Name = "OptCustomOptimizer";
        SupportsMultiObjectiveOptimization = true;
        
        PrintTo = PrintTo.OutputTab2;
        }
        else if (State == State.Configure && Strategies.Count > 0)
        {
        enumIndexes = new int[Strategies[0].OptimizationParameters.Count];
        NumberOfIterations = GetParametersCombinationsCount(Strategies[0]);
        dateIndex = 1;
        iterationIndex = 1;
        }
        }
        
        protected override void OnOptimize()
        {
        Iterate(0);
        }
        
        /// <summary>
        /// This methods iterates the parameters recursively. The actual back test is performed as the last parameter is iterated.
        /// </summary>
        /// <param name="parameterIndex"></param>
        private void Iterate(int parameterIndex)
        {
        if (Strategies[0].OptimizationParameters.Count == 0)
        return;
        
        Parameter parameter = Strategies[0].OptimizationParameters[parameterIndex];
        
        while (dateIndex <= 3)
        {
        for (int i = 0; ; i++)
        {
        if (IsAborted)
        return;
        
        if (parameter.ParameterType == typeof(int))
        {
        if ((int) parameter.Min + i * parameter.Increment > (int) parameter.Max + parameter.Increment / 1000000)
        return;
        parameter.Value = (int) parameter.Min + i * parameter.Increment;
        }
        else if (parameter.ParameterType == typeof(double))
        {
        if ((double) parameter.Min + i * parameter.Increment > (double) parameter.Max + parameter.Increment / 1000000)
        return;
        parameter.Value = (double) parameter.Min + i * parameter.Increment;
        }
        else if (parameter.ParameterType == typeof(bool))
        {
        if (i == 0)
        parameter.Value = parameter.Min;
        else if (i == 1 && (bool) parameter.Min != (bool) parameter.Max)
        parameter.Value = !(bool) parameter.Value;
        else
        return;
        }
        else if (parameter.ParameterType.IsEnum)
        {
        if (enumIndexes[parameterIndex] >= parameter.EnumValues.Length)
        {
        enumIndexes[parameterIndex] = 0;
        return;
        }
        else
        parameter.Value = parameter.EnumValues[enumIndexes[parameterIndex]++];
        }
        
        if (iterationIndex == NumberOfIterations)
        {
        if (dateIndex == 1)
        {
        Strategies[0].From = Convert.ToDateTime("5/9/2022 12:00:00 AM");
        Strategies[0].To = Convert.ToDateTime("5/9/2022 12:00:00 AM");
        }
        else if (dateIndex == 2)
        {
        Strategies[0].From = Convert.ToDateTime("5/2/2022 12:00:00 AM");
        Strategies[0].To = Convert.ToDateTime("5/2/2022 12:00:00 AM");
        }
        dateIndex = dateIndex + 1;
        iterationIndex = 1;
        Print("dateIndex(if): " + dateIndex);
        Iterate(0);
        }
        
        if (parameterIndex == Strategies[0].OptimizationParameters.Count - 1) // Is this the Last parameter -> run the iteration
        {
        Print("dateIndex(else if): " + dateIndex);
        Print("iterationIndex: " + iterationIndex);
        Print("parameterIndex: " + parameterIndex);
        Print("parameter.Name = " + parameter.Name);
        Print("parameter.Value = " + parameter.Value);
        Print("From: " + Strategies[0].From);
        Print("To: " + Strategies[0].To);
        
        RunIteration();
        iterationIndex = iterationIndex + 1;
        }
        else // Iterate next parameter in line
        Iterate(parameterIndex + 1);
        }
        // END: For loop
        }
        // END: While loop
        }
        }
        }
        I simply wanted to see if I place an outer loop on top of the FOR loop in the Iterate() method whether I would achieve my goal, but sadly it does not appear to have "worked" in the sense that the output only retains the runs for 5/2/2022 in this stylized example...
        Last edited by TheFil; 06-01-2022, 12:18 PM.

        Comment


          #5
          Hello TheFil,

          I am still not clear on what the goal is here, changing the dates from code would essentially skip the user interface selection which is part of the point of using the backtesting tool. Are you trying to set defaults for the from and to date?

          I couldn't suggest any code wise solution here, the DataSeries in the platform in general are not intended to be changed dynamically using code.

          JesseNinjaTrader Customer Service

          Comment


            #6
            The goal is to execute a batch of optimizations which shift monthly or weekly in their time frame. So instead of running the optimization for JanXX and then having to manually adjust the dates to FebXX and then clicking "Run" (and so on and so forth) you have a single point of entry and at the conclusion of all iterations the code adjusts the dates (which would be contained in an array, not hardcoded as in my example code) and the next optimization in the batch runs. This repeats until all dates in the date array have been iterated.

            Let me know if that makes more sense...

            Comment


              #7
              Hello TheFil,

              You could look at the genetic optimizer for an example of working with sets of dates however you still select the max range of dates from the user interface. As mentioned there is not really any support for changing data dynamically during a running test, the start/end date were already selected at the start.

              JesseNinjaTrader Customer Service

              Comment


                #8
                Not sure if this helps but I set parameters; a "maxCalcDate" and a "minCalcDate" which my strategy uses as a minimum requirement for any entry actions.
                So when it runs, a trade will only happen within the specified time frame.
                Note: the range of the optimizer would be set to greater than maxCalcDate and less than minCalcDate..

                Walt.
                Last edited by waltS; 08-07-2022, 03:46 PM.

                Comment

                Latest Posts

                Collapse

                Topics Statistics Last Post
                Started by Kraken29, Today, 03:24 PM
                1 response
                3 views
                0 likes
                Last Post NinjaTrader_Clayton  
                Started by Skifree, Today, 11:47 AM
                5 responses
                19 views
                0 likes
                Last Post Skifree
                by Skifree
                 
                Started by ETFVoyageur, Today, 10:34 AM
                10 responses
                23 views
                0 likes
                Last Post ETFVoyageur  
                Started by traderzoso, 12-27-2020, 05:19 PM
                6 responses
                229 views
                0 likes
                Last Post lekor
                by lekor
                 
                Started by ETFVoyageur, 05-18-2024, 12:45 AM
                4 responses
                27 views
                0 likes
                Last Post NinjaTrader_BrandonH  
                Working...
                X