Announcement

Collapse
No announcement yet.

Partner 728x90

Collapse

Strategy Output Window Skipping First Print Line

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

    Strategy Output Window Skipping First Print Line

    Working on writing a strategy and I'm printing to the output window however the strategy is skipping the first print line which is Time in this case. Prior to putting the print line for Time in there it was skipping the 1m ATR and prior to having both 1m ATR and Time print lines in it was not printing the 15m ATR.

    Secondly any chance there are more examples of multi-time frame strategies that have been handed out? I'm curious about the purpose of a few lines in the SampleMultiTimeFrame;

    For example
    if (sma50B1 == null || sma50B2 == null || sma5B1 == null || sma5B2 == null) -> is the purpose of this line in your SampleMultiTimeFrame just to make sure that the indicators aren't instantiated prior to assigning the values in the next few lines?

    What's the purpose of the lines
    if (BarsInProgress !=0)
    return;
    Does this make sure that you're only using the primary data series? Is there any benefit to having something like

    if (BarsInProgress==0)
    do primary bar data stuff
    if (BarsInProgress ==1)
    do bars array 1 stuff
    so on for the rest of the data?

    Curious because I tried to copy the format of the SampleMultiTimeFrame for the code below but still not really sure how this is supposed to work.

    Anyways here's the code that's not printing right.

    Code:
    //This namespace holds Strategies in this folder and is required. Do not change it.
    namespace NinjaTrader.NinjaScript.Strategies
    {
    public class MTF_ATR : Strategy
    {
    private Indicators.RegressionChannel RegressionChannel1;
    private ATR ATR1;
    private ATR ATR2;
    private ATR ATR3;
    private ATR ATR4;
    private ATR ATR5;
    private Indicators.VWAP8 VWAP;
    private Indicators.StdDev std_deviation;
    
    protected override void OnStateChange()
    {
    if (State == State.SetDefaults)
    {
    Description = @"MTF_ATR";
    Name = "MTF_ATR";
    Calculate = Calculate.OnBarClose;
    EntriesPerDirection = 1;
    EntryHandling = EntryHandling.AllEntries;
    IsExitOnSessionCloseStrategy = true;
    ExitOnSessionCloseSeconds = 30;
    IsFillLimitOnTouch = false;
    MaximumBarsLookBack = MaximumBarsLookBack.TwoHundredFiftySix;
    OrderFillResolution = OrderFillResolution.Standard;
    Slippage = 0;
    StartBehavior = StartBehavior.WaitUntilFlat;
    TimeInForce = TimeInForce.Gtc;
    TraceOrders = false;
    RealtimeErrorHandling = RealtimeErrorHandling.StopCancelClose;
    StopTargetHandling = StopTargetHandling.PerEntryExecution;
    BarsRequiredToTrade = 6900;
    // Disable this property for performance gains in Strategy Analyzer optimizations
    // See the Help Guide for additional information
    IsInstantiatedOnEachOptimizationIteration = true;
    }
    else if (State == State.Configure)
    {
    AddDataSeries(Data.BarsPeriodType.Minute, 15); // Array[1]
    AddDataSeries(Data.BarsPeriodType.Minute, 60); // Array[2]
    AddDataSeries(Data.BarsPeriodType.Minute, 240); // Array[3]
    AddDataSeries(Data.BarsPeriodType.Day, 4); // Array[4]
    }
    else if (State == State.DataLoaded)
    {
    ATR1 = ATR(9);
    }
    }
    
    
    
    
    protected override void OnBarUpdate()
    {
    //Add your custom strategy logic here.
    if (CurrentBar < BarsRequiredToTrade)
    return;
    
    if (ATR2 == null || ATR3 == null || ATR4 == null || ATR5 == null)
    {
    ATR2 = ATR(BarsArray[1], 9);
    ATR3 = ATR(BarsArray[2], 9);
    ATR4 = ATR(BarsArray[3], 9);
    ATR5 = ATR(BarsArray[4], 4);
    
    // Print("1 min ATR: " + ATR1[0]);
    // Print("15 min ATR: " +ATR2[0]);
    // Print("60 min ATR: " +ATR3[0]);
    // Print("4 hr ATR: " + ATR4[0]);
    // Print("4 day ATR: " + ATR5[0]);
    }
    // if (BarsInProgress ==0)
    // Print("Time: " +Time[0]);
    // Print("1 min ATR: " + ATR1[0]);
    
    if (BarsInProgress !=0)
    Print("Time: " + Time[0]);
    Print("1 min ATR: " + ATR1[0]);
    Print("15 min ATR: " +ATR2[0]);
    Print("1 hr ATR: " +ATR3[0]);
    Print("4 hr ATR: " + ATR4[0]);
    Print("4 day ATR: " + ATR5[0]);
    }
    }
    }

    #2
    Hello itsthefriz,

    Thanks for your post.

    If I understand correctly, you are applying this to a chart of 1-minute bars. The chart bars would be the primary series and would be known as BarsArray[0].

    The BarsInProgress value tells you which of the data series is calling the OnBarUpdate() method and this is a key concept to understand about multi series coding.

    When the chart bars call the OnBarUpdate(), BarsInProgress is 0, when the 15 minute series calls OnBarUpdate() then BarsInProgress will be 1, etc. etc.

    To help you understand which data series is calling the OnBarUpdate() I would suggest using a print statement like this (at the top of OnBarUpdate):

    Print ("BIP = "+BarsInProgress+" Close time of bar = "+Times[BarsInProgress][0]+" Currentbar of series= "+CurrentBars[BarsInProgress]); // display BarsInProgress, close time of the bar of the calling data series, and current bar number of that series.

    Regarding your questions,

    "What's the purpose of the lines
    if (BarsInProgress !=0)
    return;
    Does this make sure that you're only using the primary data series?
    Yes, it prevents the code below that line from executing when the other data series are calling the OnBarUpdate(). This would assume that you do not want to perform any actions when the other data series call the OnBarUpdate(). It does not mean you cannot access data from the other data series. An example of this is in the SampleMultiTimeFrame where: if (sma5B1[0] > sma50B1[0] && sma5B2[0] > sma50B2[0]) is checking the SMA from the various time frames while BarsInProgress is 0.

    Is there any benefit to having something like
    if (BarsInProgress==0)
    do primary bar data stuff
    if (BarsInProgress ==1)
    do bars array 1 stuff
    so on for the rest of the data?
    It entirely depends on what you want to do, if you want/need specific actions to be done when the other data series call the OnBarUpdate(). An example of doing something when a specific BarsInProgress is called can be seen in the OrderFlowIndicator OrderFlowCumulativeDelta. This indicator requires a 1 tick series is added and when the 1 tick series calls OnBarUpdate() then it uses BarsInProgress==1 to segment the action to update the Order Flow Cumulative Delta to keep its data synchronized. Reference: https://ninjatrader.com/support/help...ive_delta2.htm (see example at bottom of page).

    I would suggest reviewing this significant source of help for coding in a multi-series environment: https://ninjatrader.com/support/help...nstruments.htm as this will answer most all questions.

    In BarsArray[4] it looks like you are adding a 4 day bar, just wanted to point that out to make sure that is what you wanted as it seems unusual.

    When adding data series, keep in mind that the primary series (chart bars) will dictate how many days of data are loaded for the strategy. You are wanting a 4-period ATR of 4 days bars so this would mean that at a minimum the chart days to load would need to be set to 16 days and would need to be more than that (because days to load are calendar days, not trading days).

    In your code, you are checking CurrentBar, which will be the CurrentBar of the calling series. In the SampleMultiTimeFrame note that Currentbars for each data series are checked after the BarsInProgress check:

    // OnBarUpdate() will be called on incoming tick events on all Bars objects added to the strategy
    // We only want to process events on our primary Bars object (index = 0) which is set when adding
    // the strategy to a chart
    if (BarsInProgress != 0)
    return;

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


    Keep this in mind relative to trying to access the 4 period ATR on your 4day bar series as well as the other data series as that will prevent bar access errors (but again means you need a lot of historical data).

    if (sma50B1 == null || sma50B2 == null || sma5B1 == null || sma5B2 == null) -> is the purpose of this line in your SampleMultiTimeFrame just to make sure that the indicators aren't instantiated prior to assigning the values in the next few lines?
    It is to make sure that they are instantiated before accessing them. If ANY of them are null (which would be true the first time) then they are initialized and no long null so this would occur once. Note: The lines 80-83 could actually be done in State.DataLoaded and this would be the recommended practice for all indicators used in the strategy.

    Comment


      #3
      Thanks Paul,

      Naturally understanding how the data is processed seems to be the hardest part of properly telling the system how to process the data.

      Any chance you might know why the script in the first post is skipping the first line of the print statement? Last time I was running running the script the print time statement was not printing to the output window. If the print time statement was commented out then the print 1m ATR was not printing to the output window.

      That one does have me a little confused

      Comment


        #4
        Hello

        Looking at just this section:


        if (BarsInProgress !=0)
        Print("Time: " + Time[0]);
        Print("1 min ATR: " + ATR1[0]);
        Print("15 min ATR: " +ATR2[0]);
        Print("1 hr ATR: " +ATR3[0]);
        Print("4 hr ATR: " + ATR4[0]);
        Print("4 day ATR: " + ATR5[0]);


        You are missing the encapsulation { } brackets for the If statement. So the first line after the statement would be skipped on any other data series calling the OnBarUpdate() and the rest of the prints would be printed.

        Correct like this:

        if (BarsInProgress !=0)
        {
        Print("Time: " + Time[0]);
        Print("1 min ATR: " + ATR1[0]);
        Print("15 min ATR: " +ATR2[0]);
        Print("1 hr ATR: " +ATR3[0]);
        Print("4 hr ATR: " + ATR4[0]);
        Print("4 day ATR: " + ATR5[0]);
        }

        Comment


          #5
          Ah dang, that easy. Thanks Paul!

          Comment


            #6
            Hello Paul H.,

            I've been trying to make sense of the BarsInProgress concept for my own multi-timeframe script. My code's primary time frame is a 20 min chart, but I also want to get the LinRegSlope from the Day, Week, and Month charts of the same instrument. I have been running my code on the same day over and over again using Playback (market replay data) and sometimes the codes prints the LinRegSlope values, other times it only outputs 0.

            I suspected it had something to do with the BarsInProgres, so I tried your recommendation of printing the BIP and CurrentBars; see below.
            The BarsInProgress value tells you which of the data series is calling the OnBarUpdate() method and this is a key concept to understand about multi series coding.

            When the chart bars call the OnBarUpdate(), BarsInProgress is 0, when the 15 minute series calls OnBarUpdate() then BarsInProgress will be 1, etc. etc.

            To help you understand which data series is calling the OnBarUpdate() I would suggest using a print statement like this (at the top of OnBarUpdate):

            Print ("BIP = "+BarsInProgress+" Close time of bar = "+Times[BarsInProgress][0]+" Currentbar of series= "+CurrentBars[BarsInProgress]); // display BarsInProgress, close time of the bar of the calling data series, and current bar number of that series.
            During the times when the script is not working the "Currentbar of series" for the nonprimary time frames are 0, but when it works I get values in the ~100 to ~260 range.

            Any idea on what is causing this inconsistency??

            Here is a snippet of my code:
            Code:
            else if (State == State.Configure)
            {
            AddDataSeries(Data.BarsPeriodType.Month, 1); // Adds the Monthly candle data series to the code
            AddDataSeries(Data.BarsPeriodType.Week, 1); // Adds the Weekly candle data series to the code
            AddDataSeries(Data.BarsPeriodType.Day, 1); // Adds the Daily candle data series to the code
            }
            else if (State == State.DataLoaded)
            {
            //Making, and plotting the EMA indicator
            Selected_ATM = Select_an_ATM;
            EMA2 = EMA(Close, Convert.ToInt32(EMAPeriod));
            EMA2.Plots[0].Brush = Brushes.Goldenrod;
            AddChartIndicator(EMA2);
            
            }
            }
            
            protected override void OnBarUpdate()
            {
            Print ("BIP = "+BarsInProgress+" Close time of bar = "+Times[BarsInProgress][0]+" Currentbar of series= "+CurrentBars[BarsInProgress]); // display BarsInProgress, close time of the bar of the calling data series, and current bar number of that series.
            
            //Getting the Linear regression slope (quantitative trend values) for the different time frames
            
            LinRegSlopeMonth = LinRegSlope(Closes[1], SlopePeriod);
            LinRegSlopeWeek = LinRegSlope(Closes[2], SlopePeriod);
            LinRegSlopeDay = LinRegSlope(Closes[3], SlopePeriod);
            }

            Comment


              #7
              I figured out the issue! I needed to use the following syntax to load in enough bars for the LinRegSlope indicator.
              Code:
              AddDataSeries(string instrumentName, BarsPeriod barsPeriod, int barsToLoad, string tradingHoursName, bool? isResetOnNewTradingDay)

              Comment


                #8
                Hello nnwakaihe,

                Thanks for your post and welcome to the NinjaTrader forums!

                Glad you were able to resolve!

                Don't hesitate to create a new topic/thread when you have a question.

                Comment

                Latest Posts

                Collapse

                Topics Statistics Last Post
                Started by NullPointStrategies, Yesterday, 05:17 AM
                0 responses
                75 views
                0 likes
                Last Post NullPointStrategies  
                Started by argusthome, 03-08-2026, 10:06 AM
                0 responses
                146 views
                0 likes
                Last Post argusthome  
                Started by NabilKhattabi, 03-06-2026, 11:18 AM
                0 responses
                79 views
                0 likes
                Last Post NabilKhattabi  
                Started by Deep42, 03-06-2026, 12:28 AM
                0 responses
                50 views
                0 likes
                Last Post Deep42
                by Deep42
                 
                Started by TheRealMorford, 03-05-2026, 06:15 PM
                0 responses
                54 views
                0 likes
                Last Post TheRealMorford  
                Working...
                X