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

Future expiry / rollover date and backtesting

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

    Future expiry / rollover date and backtesting

    Hi,
    I am trading futures and my merge policy is "Merge non back adjusted".
    I am aware that NT does not hold the information of the real expiration of a future contract but something which NT calls "rollover date".
    I found a attribute of the instrument object which is called "expiry" but it actually holds the rollover date. Maybe the name can be changed to "rolloverDate" or something?
    Is NT somewhere holding the real expiration?

    Another question is:
    I have a back testing period of lets say 2 years. I experience that during the back-test of the 2 years the instrument always holds the "expiration" of the future contract which I am back-testing with. Is there a way to get the "expiry" of the future 2 years ago?

    Example:
    I am back-testing with the contract "FGBL 06-21". The instrument object always returns the "expiry" of 01.06.2021 no matter if the back-test is currently 2 years ago or now.
    Is there a way to change that?

    Thanks,
    Klaus

    #2
    Just found the Rollover Collection. Sorry for bothering!

    Comment


      #3
      Hello Klaus,

      Are you wanting the <rolloverobject>.Date?


      You may find the RolloverIndications indicator helpful.
      Shows a button on the chart to roll the expiry to the next available contract month. Option to hide button until a number of days before or on roll date. Another option to confirm by opening the instrument overlay selector or automatically rollover without confirmation. (Update June 27th, 2019 &#8211; Added an option to show [&#8230;]
      Chelsea B.NinjaTrader Customer Service

      Comment


        #4
        Hi Chelsea,
        yes, that's been the information I was looking for. Thanks so much.
        Klaus

        Comment


          #5
          Hello Chelsea,

          I tried to get the rollover date with

          Print(Bars.Instrument.MasterInstrument.RolloverCol lection.rollover.ContractMonth); but this seems not to work.

          What can I do?

          Kind regards
          Gerik

          Comment


            #6
            Hello Gerik,

            RolloverCollection is a collection. You will need to choose a specific rollover in this collection.

            Have a look at the example in the help guide which loops through rollover collection and prints each rollover element in the collection.
            Chelsea B.NinjaTrader Customer Service

            Comment


              #7
              Hello Chelsea,

              how can I retrieve the rolloverdate from the current instrument?

              I assume, I have to loop through the rollovercollection and match it with the current instrument.

              Is there any example how to achieve that?

              The objective is to identify in advance when the expiry of the current instrument will be to avoid a settlement.

              Kind regards
              Gerik

              Comment


                #8
                Hello Gerik,

                On lines 186 - 188, in the RolloverIndications_NT8 linked in post# 3, the current rollover (activeExpiry) is found by looping through the Instrument.MasterInstrument.RolloverCollection. This is used on line 212.

                Below is a link to the help guide on the RolloverCollection.
                Chelsea B.NinjaTrader Customer Service

                Comment


                  #9
                  Hello Chelsea,

                  using the indicator, for MESZ21 or MES 12-21 I receive 07 December 2021 as the rollover date although the settlement is 17 December 2021.

                  How can I retrieve the settlement date, which would be 17 December 2021?

                  Kind regards
                  Gerik

                  Comment


                    #10
                    Hello Gerik,

                    NinjaTrader does not store the settlement date. Only the rollover.Date as it would be shown in the Instrument -> Contract months window.
                    Chelsea B.NinjaTrader Customer Service

                    Comment


                      #11
                      Hello Chelsea,

                      thank you for your answer. May I ask the following in addition?
                      1. The rollover.Date would be the first date when the rollover can be initiated until the settlement date, right?
                      2. The period where the rollover is possible is the rollover.date + 10 days. Is it true?
                      Kind regards
                      Gerik

                      Comment


                        #12
                        Hello Gerik,

                        The rollover date is generally about a week before the last trading day, however this is not always the case.

                        The rollover date is used for NinjaTrader to merge historical data on the chart. It is also used for the Tools -> Database management -> Rollover button. These dates can be modified and typically a product can be traded before the rollover date.

                        Below is a link to a page that includes a link to the trading calendar for you to compare.
                        NinjaTrader is a leading futures broker & trading platform provider with deep discount commissions as low as $.09 per Micro contract. Start your FREE demo powered by live data.
                        Chelsea B.NinjaTrader Customer Service

                        Comment


                          #13
                          Hi Chelsea, I've looked at your Rollover indications script. I'd like to use the rollover part only without any display and anything else that's not necessary for the following AddDataSeries method purpose.
                          There's a serious lack/flaw in the instrument reference of the AddDataSeries currently only accepting hardcoded string expiry reference (with disadvantage to non Kinetic subscribers Multi-brokers licence owners as a result).
                          The problem details
                          How to Add A New Instrument Series without the Expiry date?

                          and
                          I'm trying to add a new instrument series with AddDataSeries() (https://ninjatrader.com/support/helpGuides/nt8/NT%20HelpGuide%20English.html?adddataseries.htm) I see on the example page we specify the expiration date as for example &quot;ES 09-16&quot; protected override void OnStateChange() { if (State ==


                          How to strip your code to the bare minimum needed to add the dynamic expiry reference to the AddDataSeries method? Thanks!
                          Last edited by PaulMohn; 03-24-2022, 05:14 PM.

                          Comment


                            #14
                            Chelsea, i found a partial solution from the MasterInstrument.GetNextExpiry() doc

                            For example, that works on a CL 05-22 1 Minute Chart

                            PHP Code:
                            AddDataSeries("CL "+Bars.Instrument.MasterInstrument.GetNextExpiry(DateTime.Now).ToString("MM-yy"), BarsPeriodType.Day1); 

                            How do I do the same but with a "GC " AddDataSeries() added on a CL 05-22 1 min Chart?

                            I tested that but it doesn't work
                            PHP Code:
                            AddDataSeries("GC "+Bars.Instrument.MasterInstrument.GetNextExpiry(DateTime.Now).ToString("MM-yy"), BarsPeriodType.Day1); 

                            I suspect it is because the reference is to the MasterInstrument and i think that is CL / the instrument of the series of the chart the AddDataSeries() is added to.

                            Is there something like Bars.Instrument.<GOLD>.GetNextExpiry() ?
                            PHP Code:
                            AddDataSeries("GC "+Bars.Instrument.<GOLD>.GetNextExpiry(DateTime.Now).ToString("MM-yy"), BarsPeriodType.Day1); 

                            Thanks!


                            I've checked the Instrument.GetInstrument() doc

                            and got to this working syntax
                            PHP Code:

                            else if (State == State.Configure)
                            {
                               
                            Instrument Gold Instrument.GetInstrument("GC");
                               
                            AddDataSeries("GC "+Gold.MasterInstrument.GetNextExpiry(DateTime.Now).ToString("MM-yy"), BarsPeriodType.Day1);


                            But somehow it doesn't return the correct NextExpiry Month string value for GC (it returns 03-22 instead of the correct GC next expiry Month from now which is 04-22)
                            Indicator 'DailyRanges': Error on calling 'OnStateChange' method: 'AddDataSeries' method only accepts valid instrument names. Either 'GC 03-22' does not exist in the Instrument Manager or the specified exchange has not been configured.
                            How to get it to return the correct next expiry month? Thanks!


                            I did further tests on a GC 04-22 1 min chart with this script
                            PHP 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;
                            using NinjaTrader.NinjaScript.DrawingTools;
                            #endregion

                            //This namespace holds Indicators in this folder and is required. Do not change it.
                            namespace NinjaTrader.NinjaScript.Indicators
                            {
                              public class 
                            DailyRanges Indicator
                              
                            {
                                private 
                            Series<doubleCLSeries;
                                private 
                            Series<doubleESSeries;

                                protected 
                            override void OnStateChange()
                                {
                                  if (
                            State == State.SetDefaults)
                                  {
                                    
                            Description                 = @"Enter the description for your new custom Indicator here.";
                                    
                            Name                     "DailyRanges";
                                    
                            Calculate                 Calculate.OnBarClose;
                                    
                            IsOverlay                 true;
                                    
                            DisplayInDataBox               true;
                                    
                            DrawOnPricePanel               true;
                                    
                            DrawHorizontalGridLines           true;
                                    
                            DrawVerticalGridLines           true;
                                    
                            PaintPriceMarkers             true;
                                    
                            ScaleJustification             NinjaTrader.Gui.Chart.ScaleJustification.Right;
                                    
                            //Disable this property if your indicator requires custom values that cumulate with each new market data event.
                                    //See Help Guide for additional information.
                                    
                            IsSuspendedWhileInactive           true;
                                  }
                                  else if (
                            State == State.Configure)
                                  {
                            //       Instrument Gold = Instrument.GetInstrument("GC");
                            //       AddDataSeries("GC "+Gold.MasterInstrument.GetNextExpiry(DateTime.Now ).ToString("MM-yy"), BarsPeriodType.Day, 1);
                                    
                            AddDataSeries("CL 05-22"BarsPeriodType.Day1);
                                    
                            AddDataSeries("ES 06-22"BarsPeriodType.Day1);
                                  }
                                  else if (
                            State == State.DataLoaded)
                                  {
                                    
                            CLSeries = new Series<double>(thisMaximumBarsLookBack.Infinite);
                                    
                            ESSeries = new Series<double>(thisMaximumBarsLookBack.Infinite);
                                  }
                                }

                                protected 
                            override void OnBarUpdate()
                                {

                                  if (
                            CurrentBars[0] < 55 || CurrentBars[1] < 4) return;

                                  
                            Draw.TextFixed(this"tag1""The current expiry is " Bars.Instrument.MasterInstrument.GetNextExpiry(Dat eTime.Now).ToString("MM-yy"), TextPosition.BottomRight);

                                  
                            NinjaTrader.Gui.Tools.SimpleFont myFont = new NinjaTrader.Gui.Tools.SimpleFont("Courier New"12) { Size 12Bold true };

                                  if (
                            BarsInProgress == 0)
                                  {
                                    
                            CLSeries[0] = Highs[1][0]-Lows[1][0];

                                    
                            Draw.TextFixed(
                                      
                            this,
                                      
                            "GCSeries",
                                      
                            "GC DRange: "+CLSeries[0],
                                      
                            TextPosition.TopRight,
                                      
                            Brushes.White,
                                      
                            myFont,
                                      
                            Brushes.Transparent,
                                      
                            Brushes.Transparent,
                                      
                            0);

                                    
                            ESSeries[0] = Highs[2][0]-Lows[2][0];

                                    
                            Draw.TextFixed(
                                      
                            this,
                                      
                            "ESSeries",
                                      new 
                            String('\n'1)+"ES DRange: "+Instrument.MasterInstrument.RoundToTickSize(ESSeries[0] / TickSize),
                                      
                            TextPosition.TopRight,
                                      
                            Brushes.White,
                                      
                            myFont,
                                      
                            Brushes.Transparent,
                                      
                            Brushes.Transparent,
                                      
                            0);
                                  }
                                }
                              }
                            }

                            #region NinjaScript generated code. Neither change nor remove.

                            namespace NinjaTrader.NinjaScript.Indicators
                            {
                              public 
                            partial class Indicator NinjaTrader.Gui.NinjaScript.IndicatorRenderBase
                              
                            {
                                private 
                            DailyRanges[] cacheDailyRanges;
                                public 
                            DailyRanges DailyRanges()
                                {
                                  return 
                            DailyRanges(Input);
                                }

                                public 
                            DailyRanges DailyRanges(ISeries<doubleinput)
                                {
                                  if (
                            cacheDailyRanges != null)
                                    for (
                            int idx 0idx cacheDailyRanges.Lengthidx++)
                                      if (
                            cacheDailyRanges[idx] != null && cacheDailyRanges[idx].EqualsInput(input))
                                        return 
                            cacheDailyRanges[idx];
                                  return 
                            CacheIndicator<DailyRanges>(new DailyRanges(), inputref cacheDailyRanges);
                                }
                              }
                            }

                            namespace 
                            NinjaTrader.NinjaScript.MarketAnalyzerColumns
                            {
                              public 
                            partial class MarketAnalyzerColumn MarketAnalyzerColumnBase
                              
                            {
                                public 
                            Indicators.DailyRanges DailyRanges()
                                {
                                  return 
                            indicator.DailyRanges(Input);
                                }

                                public 
                            Indicators.DailyRanges DailyRanges(ISeries<doubleinput )
                                {
                                  return 
                            indicator.DailyRanges(input);
                                }
                              }
                            }

                            namespace 
                            NinjaTrader.NinjaScript.Strategies
                            {
                              public 
                            partial class Strategy NinjaTrader.Gui.NinjaScript.StrategyRenderBase
                              
                            {
                                public 
                            Indicators.DailyRanges DailyRanges()
                                {
                                  return 
                            indicator.DailyRanges(Input);
                                }

                                public 
                            Indicators.DailyRanges DailyRanges(ISeries<doubleinput )
                                {
                                  return 
                            indicator.DailyRanges(input);
                                }
                              }
                            }

                            #endregion 

                            I noticed the Draw.TextFixed line

                            PHP Code:
                            Draw.TextFixed(this"tag1""The current expiry is " Bars.Instrument.MasterInstrument.GetNextExpiry(Dat eTime.Now).ToString("MM-yy"), TextPosition.BottomRight); 

                            Displays changing values

                            it displays
                            04-22
                            05-22
                            and
                            06-22

                            It seems to change every 2 minutes or so, to the the CL and ES expiries.

                            Why doesn't it remain 04-22? How to make it remain 04-22 (ON GC Chart)? Thanks!
                            Last edited by PaulMohn; 03-24-2022, 07:37 PM.

                            Comment


                              #15


                              Ok, I've placed the Draw.TextFixed line inside the BarsInProgress == 0 scope and now the Expiry month remains stable at 04-22.

                              PHP Code:
                              Draw.TextFixed(this"tag1""The current expiry is " Bars.Instrument.MasterInstrument.GetNextExpiry(Dat eTime.Now).ToString("MM-yy"), TextPosition.BottomRight); 
                              PHP 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;
                              using NinjaTrader.NinjaScript.DrawingTools;
                              #endregion

                              //This namespace holds Indicators in this folder and is required. Do not change it.
                              namespace NinjaTrader.NinjaScript.Indicators
                              {
                                public class 
                              DailyRanges Indicator
                                
                              {
                                  private 
                              Series<doubleCLSeries;
                                  private 
                              Series<doubleESSeries;

                                  protected 
                              override void OnStateChange()
                                  {
                                    if (
                              State == State.SetDefaults)
                                    {
                                      
                              Description                 = @"Enter the description for your new custom Indicator here.";
                                      
                              Name                     "DailyRanges";
                                      
                              Calculate                 Calculate.OnBarClose;
                                      
                              IsOverlay                 true;
                                      
                              DisplayInDataBox               true;
                                      
                              DrawOnPricePanel               true;
                                      
                              DrawHorizontalGridLines           true;
                                      
                              DrawVerticalGridLines           true;
                                      
                              PaintPriceMarkers             true;
                                      
                              ScaleJustification             NinjaTrader.Gui.Chart.ScaleJustification.Right;
                                      
                              //Disable this property if your indicator requires custom values that cumulate with each new market data event.
                                      //See Help Guide for additional information.
                                      
                              IsSuspendedWhileInactive           true;
                                    }
                                    else if (
                              State == State.Configure)
                                    {
                              //       Instrument Gold = Instrument.GetInstrument("GC");
                              //       AddDataSeries("GC "+Gold.MasterInstrument.GetNextExpiry(DateTime.Now ).ToString("MM-yy"), BarsPeriodType.Day, 1);
                                      
                              AddDataSeries("CL 05-22"BarsPeriodType.Day1);
                                      
                              AddDataSeries("ES 06-22"BarsPeriodType.Day1);
                                    }
                                    else if (
                              State == State.DataLoaded)
                                    {
                                      
                              CLSeries = new Series<double>(thisMaximumBarsLookBack.Infinite);
                                      
                              ESSeries = new Series<double>(thisMaximumBarsLookBack.Infinite);
                                    }
                                  }

                                  protected 
                              override void OnBarUpdate()
                                  {

                                    if (
                              CurrentBars[0] < 55 || CurrentBars[1] < 4) return;



                                    
                              NinjaTrader.Gui.Tools.SimpleFont myFont = new NinjaTrader.Gui.Tools.SimpleFont("Courier New"12) { Size 12Bold true };

                                    if (
                              BarsInProgress == 0)
                                    {
                                      
                              Draw.TextFixed(this"tag1""The current expiry is " Bars.Instrument.MasterInstrument.GetNextExpiry(Dat eTime.Now).ToString("MM-yy"), TextPosition.BottomRight);

                                      
                              CLSeries[0] = Highs[1][0]-Lows[1][0];

                                      
                              Draw.TextFixed(
                                        
                              this,
                                        
                              "GCSeries",
                                        
                              "GC DRange: "+CLSeries[0],
                                        
                              TextPosition.TopRight,
                                        
                              Brushes.White,
                                        
                              myFont,
                                        
                              Brushes.Transparent,
                                        
                              Brushes.Transparent,
                                        
                              0);

                                      
                              ESSeries[0] = Highs[2][0]-Lows[2][0];

                                      
                              Draw.TextFixed(
                                        
                              this,
                                        
                              "ESSeries",
                                        new 
                              String('\n'1)+"ES DRange: "+Instrument.MasterInstrument.RoundToTickSize(ESSe ries[0] / TickSize),
                                        
                              TextPosition.TopRight,
                                        
                              Brushes.White,
                                        
                              myFont,
                                        
                              Brushes.Transparent,
                                        
                              Brushes.Transparent,
                                        
                              0);
                                    }
                                  }
                                }
                              }

                              #region NinjaScript generated code. Neither change nor remove.

                              namespace NinjaTrader.NinjaScript.Indicators
                              {
                                public 
                              partial class Indicator NinjaTrader.Gui.NinjaScript.IndicatorRenderBase
                                
                              {
                                  private 
                              DailyRanges[] cacheDailyRanges;
                                  public 
                              DailyRanges DailyRanges()
                                  {
                                    return 
                              DailyRanges(Input);
                                  }

                                  public 
                              DailyRanges DailyRanges(ISeries<doubleinput)
                                  {
                                    if (
                              cacheDailyRanges != null)
                                      for (
                              int idx 0idx cacheDailyRanges.Lengthidx++)
                                        if (
                              cacheDailyRanges[idx] != null && cacheDailyRanges[idx].EqualsInput(input))
                                          return 
                              cacheDailyRanges[idx];
                                    return 
                              CacheIndicator<DailyRanges>(new DailyRanges(), inputref cacheDailyRanges);
                                  }
                                }
                              }

                              namespace 
                              NinjaTrader.NinjaScript.MarketAnalyzerColumns
                              {
                                public 
                              partial class MarketAnalyzerColumn MarketAnalyzerColumnBase
                                
                              {
                                  public 
                              Indicators.DailyRanges DailyRanges()
                                  {
                                    return 
                              indicator.DailyRanges(Input);
                                  }

                                  public 
                              Indicators.DailyRanges DailyRanges(ISeries<doubleinput )
                                  {
                                    return 
                              indicator.DailyRanges(input);
                                  }
                                }
                              }

                              namespace 
                              NinjaTrader.NinjaScript.Strategies
                              {
                                public 
                              partial class Strategy NinjaTrader.Gui.NinjaScript.StrategyRenderBase
                                
                              {
                                  public 
                              Indicators.DailyRanges DailyRanges()
                                  {
                                    return 
                              indicator.DailyRanges(Input);
                                  }

                                  public 
                              Indicators.DailyRanges DailyRanges(ISeries<doubleinput )
                                  {
                                    return 
                              indicator.DailyRanges(input);
                                  }
                                }
                              }

                              #endregion 

                              That suggests it must be within a BarsInProgress corresponding instrument Check to return the correct Month expiry value.
                              If that is so, how to do so within the AddDataSeries? Thanks!

                              Comment

                              Latest Posts

                              Collapse

                              Topics Statistics Last Post
                              Started by benmarkal, Yesterday, 12:52 PM
                              3 responses
                              22 views
                              0 likes
                              Last Post NinjaTrader_Gaby  
                              Started by helpwanted, Today, 03:06 AM
                              1 response
                              17 views
                              0 likes
                              Last Post sarafuenonly123  
                              Started by Brevo, Today, 01:45 AM
                              0 responses
                              11 views
                              0 likes
                              Last Post Brevo
                              by Brevo
                               
                              Started by aussugardefender, Today, 01:07 AM
                              0 responses
                              6 views
                              0 likes
                              Last Post aussugardefender  
                              Started by pvincent, 06-23-2022, 12:53 PM
                              14 responses
                              244 views
                              0 likes
                              Last Post Nyman
                              by Nyman
                               
                              Working...
                              X